Wakan Tanka
Wakan Tanka

Reputation: 8042

heredoc syntax for multi-line perl using stdin from bash

How to pass file to perl script for processing and also use heredoc syntax for multi-line perl script? I have tried those but no luck:

cat ng.input | perl -nae <<EOF
if (@F==2) {print $F[0] . "\t". $F[1] . "\n"} else { print "\t" . $F[0] . "\n" }
EOF

cat ng.input | perl -nae - <<EOF
if (@F==2) {print $F[0] . "\t". $F[1] . "\n"} else { print "\t" . $F[0] . "\n" }
EOF

Upvotes: 1

Views: 1064

Answers (3)

Ale
Ale

Reputation: 997

Can also pass a heredoc as a "-" first argument to perl:

perl -lna - ng.input <<'EOF'
if (@F==2) {print $F[0] . "\t". $F[1] . "\n"} else { print "\t" . $F[0] . "\n" }
EOF

Upvotes: 0

ikegami
ikegami

Reputation: 385590

There's really no need for here-docs. You could simply use a multi-line argument:

perl -nae'
    if (@F==2) {
       print $F[0] . "\t". $F[1] . "\n"
    } else {
       print "\t" . $F[0] . "\n"
    }
' ng.input

Clean, more portable than Barmar's, and only uses one process instead of Barmar's three.


Note that your code could be shrunk to

perl -lane'unshift @F, "" if @F!=2; print "$F[0]\t$F[1]";' ng.input

or even

perl -pale'unshift @F, "" if @F!=2; $_="$F[0]\t$F[1]";' ng.input

Upvotes: 3

Barmar
Barmar

Reputation: 780779

Use process substitution:

cat ng.input | perl -na <(cat <<'EOF'
if (@F==2) {print $F[0] . "\t". $F[1] . "\n"} else { print "\t" . $F[0] . "\n" }
EOF
)

Also put single quotes around the EOF tag so that $F in the perl script won't be expanded as shell variables.

Upvotes: 1

Related Questions