[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

RE: [Omaha.pm] Impossible perl one-liner?



If you really want a one liner, suggest this as a golf challenge on perl monks...

-Scott

-----Original Message-----
From: omaha-pm-bounces@pm.org [mailto:omaha-pm-bounces@pm.org]On Behalf
Of Jay Hannah
Sent: Thursday, March 17, 2005 6:18 PM
To: Perl Mongers of Omaha, Nebraska USA
Subject: Re: [Omaha.pm] Impossible perl one-liner?



On Mar 16, 2005, at 4:52 PM, Daniel Linder wrote:
> On Solaris, when I use "df -k" the sizes listed are in terms of KBytes.
> I'm trying to come up with a simple perl one-liner to do one of two 
> things
> to make a quick scan of the list a bit easier to 'grok':
> 1: Add a comman "," between every third digit (1234567 -> 1,234,567)
> For #1, I couldn't get a perl one-liner could do multiple 'inserts' of
> commas, especially when counting from the right-most digit and 
> progressing
> left.

I dunno in a one-liner. I wrote an 18-liner and then stumbled into many 
ideas better than mine:

http://perlmonks.thepen.com/117697.html

If you want "my way" (why would you? -laugh-):

$ df -k
Filesystem              1K-blocks     Used    Avail Capacity  Mounted on
/dev/disk0s9             39066000 15462748 23347252    40%    /
devfs                          93       93        0   100%    /dev
fdesc                           1        1        0   100%    /dev
<volfs>                       512      512        0   100%    /.vol
automount -nsl [329]            0        0        0   100%    /Network
automount -fstab [332]          0        0        0   100%    
/automount/Servers
automount -static [332]         0        0        0   100%    
/automount/static

$ cat commas.pl
#!/usr/bin/perl

while (<>) {
    $line_orig = $_;
    $line = $_;
    my @ints = /(\d\d\d\d+)/g;
    my (%conv, $orig);
    foreach $orig (@ints) {
       my @i = reverse (split //, $orig);
       for ($offset = 3; $offset < @i; $offset += 3) {
          if ($i[$offset + 1] =~ /\d/) {
             splice @i, $offset, 0, ',';
             $offset++;
          }
       }
       my $new = join "", reverse @i;
       $line =~ s/$orig/$new/g;
    }
    print $line;
}

$ df -k | ./commas.pl
Filesystem              1K-blocks     Used    Avail Capacity  Mounted on
/dev/disk0s9             39,066,000 15,462,748 23,347,252    40%    /
devfs                          93       93        0   100%    /dev
fdesc                           1        1        0   100%    /dev
<volfs>                       512      512        0   100%    /.vol
automount -nsl [329]            0        0        0   100%    /Network
automount -fstab [332]          0        0        0   100%    
/automount/Servers
automount -static [332]         0        0        0   100%    
/automount/static

Things get pretty ugly when you jack w/ the column widths of some 
columns in some rows but not all columns for all rows. To make it 
pretty perhaps you should slurp it all up then kick it all out via Perl 
formats? (See perldoc perlform).

> 2: Convert from KBytes to MBytes or GBytes by dividing by 1024 or 
> 1024^2.
> I was trying this to achieve #2:
> # echo leading text 1234567 trailing text | perl -pe 
> 's/([0-9]+)/$1\/1024/g'
> But that just returned:
> leading text 1234567/1024 trailing text
>
> I tried inserting the "eval" function, but couldn't get it to work...
>
> So, anyone else got an idea?

If you look in "perldoc perlre" you'll find "(?{ code })", which 
theoretically lets you execute code inside a regex. I've never gotten 
it to work though.

> P.s. I might end up writing a small script that uses more perl bruit 
> force
> but I thought a one-liner would be cleaner. :)

Ya. Easier to read/maintain that way. -grin-

j


_______________________________________________
Omaha-pm mailing list
Omaha-pm@pm.org
http://mail.pm.org/mailman/listinfo/omaha-pm