tags:

views:

115

answers:

4

How could I convert:

awk '{print $2 >> $1}' file

in a short Perl one-liner?

"file" could look like this:

fruit banana
vegetable beetroot
vegetable carrot
mushroom chanterelle
fruit apple

+5  A: 

there may some other ways, but here's what i can think of

perl -ane 'open(FILE,">>",$F[0]); print FILE $F[1];close(FILE);' file
ghostdog74
+1 for pure Perl @ghostdog.
codaddict
Name can change but the quality of answers remain the same :)
codaddict
+2  A: 

Not pure Perl, but you can do:

perl -nae '`echo $F[1] >> $F[0]`' input_file
codaddict
For small, quick-and-dirty jobs I would take this one. I hope nobody will tar and feather me because I didn't choose an answer with a pure Perl solution.
sid_com
+4  A: 

I guess awk has to be better at some things :-)

This is right at the limit of what I'd do on the command line, but it avoids reopening filehandles.

$ perl -lane '$fh{$F[0]} || open $fh{$F[0]}, ">>", $F[0]; print {$fh{$F[0]}} $F[1]' file
davorg
as I understand it, this is what awk does.
glenn jackman
+1  A: 

This is what a2p <<< '{print $2 >> $1}' produces

#!/usr/bin/perl
eval 'exec /usr/bin/perl -S $0 ${1+"$@"}'
    if $running_under_some_shell;
                        # this emulates #! processing on NIH machines.
                        # (remove #! line above if indigestible)

eval '$'.$1.'$2;' while $ARGV[0] =~ /^([A-Za-z_0-9]+=)(.*)/ && shift;
                        # process any FOO=bar switches

$, = ' ';               # set output field separator
$\ = "\n";              # set output record separator

while (<>) {
    ($Fld1,$Fld2) = split(' ', $_, -1);
    &Pick('>>', $Fld1) &&
        (print $fh $Fld2);
}

sub Pick {
    local($mode,$name,$pipe) = @_;
    $fh = $name;
    open($name,$mode.$name.$pipe) unless $opened{$name}++;
}
glenn jackman