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

I'm currently using two one-liners to 1. Extract information from a tab-delimited .txt file and then 2. Replace a set of strings within the newly created file:

perl -lane '$w = "w"; $l = length($F[9]); print "$w\t$F[2]\t$F[3]\t$l" if $F[1] =~ 99; $w = "c"; $l = length($F[9]); $p = $F[3]+$l; print "$w\t$F[2]\t$p\t$l" if $F[1] =~ 83; print "Head1\tHead2\tHead3\tHead4" if $.==1;'

perl -ane '$F[1] =~ s/A/B/; $F[1] =~ s/C/D/; $F[1] =~ s/F/G/; say join "\t", @F'

Is there a way to combine these into a single line such that it performs this replacement before printing the new file?

Replies are listed 'Best First'.
Re: Performing search and replace on an output file prior to printing
by Eily (Monsignor) on Jan 26, 2016 at 09:55 UTC

    The way I'd do it is put the values in an array, process the array and print it with either $, or $" set to "\t".
    BEGIN { $,="\t"; print "Head1".."Head4"; } @v = ("w", $F[2], $F[3], length($F[9])); $v[0] = "c" and $v[2]++ if $F[1] =~ /83/; v[1] =~ tr/ACF/BDG/; print @v if $F[1] =~ /99|83/;
    Untested, since I didn't have input data :).

    "Head1".."Head4" is a little bit of perl magic to print your headers. tr will replace every occurrence of the letters, not just the first like you did, but you get the idea.

    Edit: removed useless slice on first definition of @v.

    Edit: replaced all the $v{X} by $v[X]

      Can you clarify "removed useless slice"? I know this is not a golf problem, but one liners are a place where brevity can be useful. As I see it:

      @v = ("w", @F[2,3], length($F[9]))

      is valid syntax and would save 5 characters.

      But God demonstrates His own love toward us, in that while we were yet sinners, Christ died for us. Romans 5:8 (NASB)

        would save 5 characters.
        @v = ("w", @F[2,3], length($F[9])) @v = ("w", @F[2,3], length $F[9]) # -1 more!
        ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,

        I started with @v{1,3} = (...) and a separate computation of $v[0] and $v[2]. But I turned that into @v{0,1,2,3} = (...), where the slice on @v is not only useless, but also incorrect now that I think of it (since it was actually a slice on %v). And yes the code can be shorter (there is a lot of unnecessary white space for example), but I was expecting TJCooper to adapt the oneliner to his needs anyway.

      Great, thank you! That makes sense after i've adapted it.