Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > Forcing list context

Reply
Thread Tools

Forcing list context

 
 
Brian Greenfield
Guest
Posts: n/a
 
      12-31-2003
I was writing a script that needed to find the free space on a mounted
Linux partition (mounted on /backup) and I wrote the following
snippet:

my @res = split /\s+/, grep m{/backup}, `df`; # 1

The problem being that the second argument of split is evaluated in
scalar context so grep returns the number of matches instead of the
actual match (there will only ever be a single match). I got round
this problem by inserting a join so that grep is evaluated in list
context:

my @res = split /\s+/, join '', (grep m{/backup}, `df`); # 2

While this works, it seems a little kludgey. I know I could have
indexed grep's list result:

my @res = split /\s+/, (grep m{/backup}, `df`)[0]; # 3

I intended to go on to do a list splice to get the fields I wanted
(the second to fourth) and I wanted to avoid the using indexing twice:

my @res = (split /\s+/, (grep m{/backup}, `df`)[0])[1..3]; # 4

I ended up using the splice with method 2:

my @res = (split /\s+/,
join '', (grep m{/backup}, `df`))[1..3]; # 5

Does Perl offer any other ways of forcing list context?

Sample output from df, for reference

Filesystem 1K-blocks Used Available Use% Mounted on
/dev/hdb2 29300456 20002976 7809060 72% /backups
/dev/hdc1 12998064 3069480 9268316 25% /mirrors

 
Reply With Quote
 
 
 
 
James Willmore
Guest
Posts: n/a
 
      12-31-2003
On Wed, 31 Dec 2003 12:02:27 GMT
Brian Greenfield <not-for-> wrote:

> I was writing a script that needed to find the free space on a
> mounted Linux partition

<snip>
> Does Perl offer any other ways of forcing list context?
>
> Sample output from df, for reference
>
> Filesystem 1K-blocks Used Available Use% Mounted on
> /dev/hdb2 29300456 20002976 7809060 72% /backups
> /dev/hdc1 12998064 3069480 9268316 25% /mirrors


A simple one liner that gets what you want is ...

host> df | perl -ne 'if(/home/){@line = split;print $line[3],"\n";}'

My though is it's easier to use a regex to get what you want versus
using 'grep' in the context of what you're trying to do. However,
that's my opinion

However, you may want to look over the Filesys:iskFree module. It
may make your tasks easier


--
Jim

Copyright notice: all code written by the author in this post is
released under the GPL. http://www.gnu.org/licenses/gpl.txt
for more information.

a fortune quote ...
A little inaccuracy sometimes saves tons of explanation. -- H.
H. Munroe
 
Reply With Quote
 
 
 
 
l v
Guest
Posts: n/a
 
      12-31-2003
James Willmore wrote:
> On Wed, 31 Dec 2003 12:02:27 GMT
> Brian Greenfield <not-for-> wrote:
>
>
>>I was writing a script that needed to find the free space on a
>>mounted Linux partition

>
> <snip>
>
>>Does Perl offer any other ways of forcing list context?
>>
>>Sample output from df, for reference
>>
>>Filesystem 1K-blocks Used Available Use% Mounted on
>>/dev/hdb2 29300456 20002976 7809060 72% /backups
>>/dev/hdc1 12998064 3069480 9268316 25% /mirrors

>
>
> A simple one liner that gets what you want is ...
>
> host> df | perl -ne 'if(/home/){@line = split;print $line[3],"\n";}'
>
> My though is it's easier to use a regex to get what you want versus
> using 'grep' in the context of what you're trying to do. However,
> that's my opinion
>
> However, you may want to look over the Filesys:iskFree module. It
> may make your tasks easier
>
>


using the perl option -a will auto-split $_ into @F, therefore

df | perl -nae 'print "$F[3]\n" if(/home/)'

Len

 
Reply With Quote
 
l v
Guest
Posts: n/a
 
      01-01-2004
Brian Greenfield wrote:

> I was writing a script that needed to find the free space on a mounted
> Linux partition (mounted on /backup) and I wrote the following
> snippet:
>
> my @res = split /\s+/, grep m{/backup}, `df`; # 1
>
> The problem being that the second argument of split is evaluated in
> scalar context so grep returns the number of matches instead of the
> actual match (there will only ever be a single match). I got round
> this problem by inserting a join so that grep is evaluated in list
> context:
>
> my @res = split /\s+/, join '', (grep m{/backup}, `df`); # 2
>
> While this works, it seems a little kludgey. I know I could have
> indexed grep's list result:
>
> my @res = split /\s+/, (grep m{/backup}, `df`)[0]; # 3
>
> I intended to go on to do a list splice to get the fields I wanted
> (the second to fourth) and I wanted to avoid the using indexing twice:
>
> my @res = (split /\s+/, (grep m{/backup}, `df`)[0])[1..3]; # 4
>
> I ended up using the splice with method 2:
>
> my @res = (split /\s+/,
> join '', (grep m{/backup}, `df`))[1..3]; # 5
>
> Does Perl offer any other ways of forcing list context?
>
> Sample output from df, for reference
>
> Filesystem 1K-blocks Used Available Use% Mounted on
> /dev/hdb2 29300456 20002976 7809060 72% /backups
> /dev/hdc1 12998064 3069480 9268316 25% /mirrors
>


I think you are attempting to do too much in one line. However @{[ ]}
can be used to force list context. Split is looking for a scalar and
you are feeding it an array of 1. Try the following:

#!/usr/bin/perl

my @result = grep m{/backups}, `df`;
mmy @res = split (/\s+/, $result[0]);

for my $r (@res) {
print "r = $r\n";
}


I would personally add the file system to the df command to lighten
greps load, if you have alot of mount points. df /backups will return
for /backups only, including the header.
my @result = grep m{/backups}, `df /backups`;

my $.02
Len

 
Reply With Quote
 
Bruce Horrocks
Guest
Posts: n/a
 
      01-01-2004
In message <>, Brian
Greenfield <not-for-> writes
>I ended up using the splice with method 2:
>
> my @res = (split /\s+/,
> join '', (grep m{/backup}, `df`))[1..3]; # 5
>
>Does Perl offer any other ways of forcing list context?


Absolutely not the answer to the question that you asked, but a neat-ish
(untested) solution is:

my $res = `df | awk '/backups/ {print $4}'`

Regards,
--
Bruce Horrocks
Surrey
England
<firstname>@<surname>.plus.com -- fix the obvious for email
 
Reply With Quote
 
Lawrence D'Oliveiro
Guest
Posts: n/a
 
      01-01-2004
In article <>,
Brian Greenfield <not-for-> wrote:

>I was writing a script that needed to find the free space on a mounted
>Linux partition (mounted on /backup)...


Just a thought, but on Linux, rather than forking df, you can read all
information on current mount points from /proc/self/mounts. This returns
one line per mount point, containing the following space-separated items:

device mountpoint filesystem flags fsck1 fsck2
 
Reply With Quote
 
John W. Krahn
Guest
Posts: n/a
 
      01-01-2004
Brian Greenfield wrote:
>
> I was writing a script that needed to find the free space on a mounted
> Linux partition (mounted on /backup) and I wrote the following
> snippet:
>
> my @res = split /\s+/, grep m{/backup}, `df`; # 1
>
> The problem being that the second argument of split is evaluated in
> scalar context so grep returns the number of matches instead of the
> actual match (there will only ever be a single match). I got round
> this problem by inserting a join so that grep is evaluated in list
> context:
>
> my @res = split /\s+/, join '', (grep m{/backup}, `df`); # 2
>
> While this works, it seems a little kludgey. I know I could have
> indexed grep's list result:
>
> my @res = split /\s+/, (grep m{/backup}, `df`)[0]; # 3
>
> I intended to go on to do a list splice to get the fields I wanted
> (the second to fourth) and I wanted to avoid the using indexing twice:
>
> my @res = (split /\s+/, (grep m{/backup}, `df`)[0])[1..3]; # 4
>
> I ended up using the splice with method 2:
>
> my @res = (split /\s+/,
> join '', (grep m{/backup}, `df`))[1..3]; # 5
>
> Does Perl offer any other ways of forcing list context?
>
> Sample output from df, for reference
>
> Filesystem 1K-blocks Used Available Use% Mounted on
> /dev/hdb2 29300456 20002976 7809060 72% /backups
> /dev/hdc1 12998064 3069480 9268316 25% /mirrors


I would do it this way:

my @res = `df /backup` =~ /(?<=\s)\d+(?=\s)/g;



John
--
use Perl;
program
fulfillment
 
Reply With Quote
 
Brian Greenfield
Guest
Posts: n/a
 
      01-01-2004
On Wed, 31 Dec 2003 18:28:12 -0600, l v <> wrote:

>Brian Greenfield wrote:
>
>> my @res = (split /\s+/,
>> join '', (grep m{/backup}, `df`))[1..3]; # 5

>
>I think you are attempting to do too much in one line.


I know. It just sorta grew

>However @{[ ]}
>can be used to force list context.


Which is what I was looking for, thanks. (Even though I wan't be using
it - I much prefer John W. Krahn method's oven my own.)
 
Reply With Quote
 
Brian Greenfield
Guest
Posts: n/a
 
      01-01-2004
On Thu, 01 Jan 2004 11:46:09 GMT, "John W. Krahn" <>
wrote:

>Brian Greenfield wrote:
>>
>> my @res = (split /\s+/,
>> join '', (grep m{/backup}, `df`))[1..3]; # 5

>
>I would do it this way:
>
>my @res = `df /backup` =~ /(?<=\s)\d+(?=\s)/g;


That's much cleaner than my overly-complicated method. Thanks John.
(And thanks for pointing out 'df /backups' - I never thought to look
first at arguments to df.
 
Reply With Quote
 
Martien Verbruggen
Guest
Posts: n/a
 
      01-01-2004
On Wed, 31 Dec 2003 12:02:27 GMT,
Brian Greenfield <not-for-> wrote:
> I was writing a script that needed to find the free space on a mounted
> Linux partition (mounted on /backup) and I wrote the following
> snippet:


[snip]

Apart from all the other suggestions you've had about parsing df output
(and mind that it can get quite complicated to do that reliably), and to
read the /proc file system directly, there is the Filesys:f module,
available from CPAN, which is a wrapper wround Filesys::Statvfs, which
is a wrapper around your system's statvfs call.

Using that will probably make your program more portable (to all
environments where statvfs is available, which includes linux, and all
major unices I know of), give you more information when needed, and most
likely is a lot faster and lighter on the machine as well.

Apart from that, there are also Filesys:iskFree (runs external df
command), and Filesys:iskSpace (calls statvfs), neither of which I've
tried.

Martien
--
|
Martien Verbruggen | Little girls, like butterflies, need no
| excuse - Lazarus Long
|
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Forcing list context on <$fh> A. Farber Perl Misc 23 03-09-2009 05:05 PM
List context versus list context Bo Lindbergh Perl Misc 12 06-28-2006 07:12 PM
Strange Context Error: Context 0x197ee0 is disconnected in VS 2005 =?Utf-8?B?U3VuU21pbGU=?= ASP .Net 0 01-10-2006 03:59 PM
Forcing Array Context Peter Kay Perl Misc 11 08-20-2004 06:53 PM
Context.Items vs Context.Handler (passing values between pages) VS_NET_DEV ASP .Net 2 05-25-2004 01:16 PM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57