http://www.perlmonks.org?node_id=1017880

abhay180 has asked for the wisdom of the Perl Monks concerning the following question:

I want to execute following perl-one-liner on a set of files (tmp_*) in a directory....
% perl -e ' while (<>) { if (/: /) { $c += (split /: /)[0]; } } prin +t "SUM.$ARGV =$c\n"' tmp_*
or
%perl -e ' while (<>) { if (/: /) { $c += (split /: /)[0]; } } print + "SUM.$ARGV =$c\n"' | xargs cat tmp_filelist
so on..... Nothing seems to work...it just does for one file and exits.... Help

Replies are listed 'Best First'.
Re: perl onliner on multiple files
by BrowserUk (Patriarch) on Feb 08, 2013 at 19:44 UTC

    This (untested) may do what you want:

    perl -nE"/: / and $c+= (split/: /)[0]; if( eof(ARGV) ){ say qq[SUM.$AR +V =$c]; $c=0 }" tmp_*
    • -n:

      provides the while(<>){} loop.

    • the if( eof(ARGV) )

      checks for the end of each individual file, prints the results and resets $c to 0.

    • $ARGV:

      gives you the names of the individual files in the output.


    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
      When i run this i get following error mesg:
      % perl -nE "/: / and $c += (split/: /)[0]; if( eof(ARGV) ){ say qq[SUM +.$ARGV =$c]; $c=0 }" tmp_* c: Undefined variable.

        Not from Perl you don't. That must be coming from your shell.

        Try switching the quotes if you are on linux. Ie:

        perl -nE'/: / and $c+= (split/: /)[0]; if( eof(ARGV) ){ say qq[SUM.$AR +V =$c]; $c=0 }' tmp_*

        If you are a perl/*nix user, you ought to know that.


        With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.
        In a bash shell, I get:
        $ perl -nE "/: / and $c += (split/: /)[0]; if( eof(ARGV) ){ say qq[SUM +.$ARGV =$c]; $c=0 }" tmp_* syntax error at -e line 1, near "+=" syntax error at -e line 1, near "; =" Execution of -e aborted due to compilation errors.

        And:

        $ c=10 $ echo c c $ echo $c 10 $ echo "The total is: $c" The total is: 10 $ echo 'The total is: $c' The total is: $c
        So within double quotes, the shell expands $variables, which of course happens *before* the shell hands the text over to the perl command. That is similar to the way the shell expands your glob: tmp_* and replaces it with a list of file names, which is what the perl command ends up seeing.
        :) Then give up the oneliners, save it to a file
Re: perl onliner on multiple files
by igelkott (Priest) on Feb 08, 2013 at 21:30 UTC

    Seems to work fine (on a reasonable number of files) if you want the total sum. If you want the sum per file, a minimal change would be to print and reset $c after each file ends.

    For example:
    perl -e ' while (<>) { if (/: /) { $c += (split /: /)[0]; } if(eof) { print "SUM.$ARGV =$c\n"; $c=0; } }' tmp_*
      Great...it works.
Re: perl oneliner on multiple files
by jwkrahn (Abbot) on Feb 09, 2013 at 01:12 UTC
    % perl -lne'/(\d+): /and$c+=$1;eof&&print"SUM.$ARGV =$c"' tmp_*
      Hi, Thanks....this also will work..but w a slight correction...need to zero out $c at eof.
      perl -lne'/(\d+): /and$c+=$1; eof&&print"SUM.$ARGV =$c"; if(eof) {$c=0 +}' tmp_1*
        perl -c -lne'/(\d+): /and$c+=$1;eof&&($c=!print"SUM.$ARGV =$c")' tmp_*
Re: perl onliner on multiple files
by Anonymous Monk on Feb 08, 2013 at 19:45 UTC
    It only prints once after you've processed all the input....