Search code examples
bashperldelimiter

bash perl options for one expression, others for another, in the same command


I have file1.txt

text1
text1
text1
text2
text2
text2
text1
text1
text1

and file2.txt

text1
text2
text2
text1
text1
text1

I have a command with pipe:

perl -pe 's/text2$/text4/' file1.txt file2.txt | perl -0pe 's/text1$/text3/'

That gives me the output:

text1
text1
text1
text4
text4
text4
text1
text1
text1    #EOF file1.txt
text1
text4
text4
text1
text1
text3    #EOF file2.txt

but I want:

text1
text1
text1
text4
text4
text4
text1
text1
text3    #EOF file1.txt
text1
text4
text4
text1
text1
text3    #EOF file2.txt

So I tried this command:

perl -pe 's/text2$/text4/; ' -0e 's/text1$/text3/' file1.txt file2.txt

Which unexpectedly applies the "null" record delimiter to both expressions and not just the last one, resulting in:

text1
text1
text1
text2
text2
text2
text1
text1
text3    #EOF file1.txt
text1
text2
text2
text1
text1
text3    #EOF file2.txt

In fact, as you can see, "text2" is never found on the last line, so it is not replaced by "text4", which would have happened if the "null" record delimiter had been applied only to the last of the two expressions.

How do I make it apply only to the last one?


Solution

  • Since slurping treats each file as a line, you can solve this by changing the order of the programs in the pipeline.

    perl -0777pe's/text1$/text3/' file1.txt file2.txt | perl -pe's/text2$/text4/'
    

    The above solution is very dependent on the specifics of the example you gave. The following is a general solution:

    for f in file1.txt file2.txt; do
       perl -pe's/text2$/text4/' -- "$f" | perl -0777pe's/text1$/text3/'
    done
    

    With some code changes, we can come up with a better solution.

    perl -0777pe's/text2$/text4/mg; s/text1$/text3/;' file1.txt file2.txt
    

    A note on your attempt

    Multiple -e options are joined with line feeds.

    $ perl -e'print "Hello,' -e'World\n"'
    Hello,
    World
    

    Placing options between -e options is therefore meaningless.