Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

!x[$1]++

Use that at least 10 times a day

Also, Larry Wall (perl) said "I still say awk '{print $1}' a lot."



Don't forget about `cut -f1` though!

Of course anything more complex than that, but not requiring the complexity of Perl/Ruby is generally best still done with Awk. In my world, that is a lot.


cut -f1 and awk '{print $1}' are not equivalent, though: awk does not count empty fields. To be precise:

    pi:~$ echo 'foo  bar' | cut -d ' ' -f 2

    pi:~$ echo 'foo  bar' | awk '{print $2}'
    bar


Just for the interested reader: when the first command line is changed into

    pi:~$ echo 'foo  bar' | tr -s ' ' | cut -d ' ' -f 2
it also outputs 'bar'. The -s (for "squeeze") option of tr turns every sequence of the specified character (space in this case) into one instance of this character.

Of course, the awk solution is more succint and elegant in this case - I just think that tr -s / cut -d is handy to know from time to time, too.


The interested reader should not assume hastily, however, that tr -s is enough to make cut behave exactly like awk. Hint: leading spaces.

    pi:~$ echo ' foo' | tr -s ' ' | cut -d ' ' -f 1 
    
    pi:~$ echo ' foo' | awk '{print $1}'
    foo


Because it's shorter than `perl -lane 'print $F[0]'`.


It's certainly easier to remember.. what's the lane?


"what's the lane?"

four options squeezed together:

-l: 1. "chomps" the input (which here means: removes newlines (if present) from each line, more general explanation: http://perldoc.perl.org/functions/chomp.html 2. and automatically adds a newline to each output newline (see below how to achieve this in a shorter way with a relatively new Perl feature).

-a: turns on auto-split-mode: this splits the input (like awk) into the @F (for fields) array. The default separator is one (or many) spaces, i.e. it behaves like AWK.

-n: makes Perl process the input in an implicit while loop around the input, which is processed line-wise: "as long as there is another line, process it!"

-e: execute the next command line argument as a Perl program (argument in this case beeing 'print $F[0]').

Note that the example can be shortened if you use -E instead of -e. -E enables all extensions and new features of Perl (which aren't enabled with -e because of backwards compatibility). This allows you to use 'say' instead of 'print' which adds a trailing newline automatically and lets you drop the -l option (if you don't need the 'chomp' behaviour explained above):

    $ perl -anE 'say $F[0]'
Of course, the AWK command line is still shorter - and that's expected, because AWK is more specialized than Perl.

Still, Perl one liners are often very useful and can do other things better / shorter than AWK - especially if the one-liner uses one of the many libraries that are available for Perl.

A thorough reference of all Perl command line options is available at:

    http://perldoc.perl.org/perlrun.html
or just:

    $ man perlrun


Thank you, that tempts me to go and look at perl. At the moment I tend to use simple awk, or a full python script. I find python really doesn't lend itself to "one line", or even particularly short, programs however. I keep meaning to go back and look at perl. I was tempted to wait for Perl 6, but I think the time has come to just look at Perl 5 :)


If you're genuinely curious about -lane, my favorite site for Perl one liners has gone the way of all flesh, but the Wayback Machine can still get you a copy[1].

[1] http://web.archive.org/web/20090602215912/http://sial.org/ho...




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: