Last updated on July 4, 2020 by Dan Nanni
Suppose you have a text file that looks like the following.
Beginning of a text file. This is a cat. This is a dog. This is a guinea pig. This is a gecko. This is a hamster. This is a parrot. This is a rabbit. This is a ferret. This is a turtle.
You want to replace the highlighted multiple lines with the following one-line, but without using a text editor.
Beginning of a text file. This is a cat. This is a dog. These were removed. This is a parrot. This is a rabbit. This is a ferret. This is a turtle.
When it comes to finding and replacing a multi-line string pattern, Perl's regular expression based pattern matching comes in handy.
The following one-liner can get the job done.
$ perl -i -0pe 's/<multi-line-string-pattern>/<replacement-string>/' input.txt
A couple of notes in the above expression:
-i
option tells Perl to perform in-place editing, meaning that Perl reads the input file, makes substitutions, and writes the results back to the same input file. If you want to dry-run the changes, you can omit this option, in which case the results will be shown to stdout
without modifying the input file.
-0
option turns Perl into "file slurp" mode, where Perl reads the entire input file in one shot (intead of line by line). This enables multi-line search and replace.
-pe
option allows you to run Perl code (pattern matching and replacement in this case) and display output from the command line.
In this particular example, the following command will replace a multi-line string as required, and display the result (without applying the change to the input file).
$ perl -0pe 's/This is a guinea pig.nThis is a gecko.nThis is a hamster.n/These were removed.n/' input.txt
Once confirming that the result is correct, you can apply the change to the input file by adding -i
option:
$ perl -i -0pe 's/This is a guinea pig.nThis is a gecko.nThis is a hamster.n/These were removed.n/' input.txt
Here are some variations:
To find a multi-line string pattern in a case-insensitive fashion:
$ perl -i -0pe 's/<multi-line-string-pattern>/<replacement-string>/i' input.txt
To remove a multi-line string pattern:
$ perl -i -0pe 's/<multi-line-string-pattern>//' input.txt
If you want to find and replace a multi-line string in more than one files, you can use a combination of find
and xargs
as follows.
$ find ~/doc -name "*.txt" | xargs perl -i -0pe 's/<multi-line-string-pattern>/<replacement-string>/'
This one-liner searches for all text files in ~/doc
folder, and apply multi-line string replacement in each file.
This website is made possible by minimal ads and your gracious donation via PayPal or credit card
Please note that this article is published by Xmodulo.com under a Creative Commons Attribution-ShareAlike 3.0 Unported License. If you would like to use the whole or any part of this article, you need to cite this web page at Xmodulo.com as the original source.
Xmodulo © 2021 ‒ About ‒ Write for Us ‒ Feed ‒ Powered by DigitalOcean