user15964 user15964 - 4 months ago 15
Perl Question

Cross-line regex match in a Perl one-liner

My question sounds trivial, but I google many page still can't not find an answer.

I am on Windows. I have a text file. If I open it with Notepad++, it looks like this

enter image description here

I want to try several things


  1. delete all carriage return and line feed

    perl -i.bak -pe "s/\r\n//g" a.txt



surprisingly, there is nothing changed. What is wrong? But according to the doc, I am pretty sure
\r
is
CR
and
\n
is
LF



  1. What I actually want to do is match across line. for example
    ^function.*\r\n!
    will match just like Notepad++ will does



enter image description here

If we want to indent the ! line if its previous line is started with "function", a naive thought would be (actually it works is notepad++)

perl -i.bak -pe "s/^(function.*\r\n)!/$1\t!/g" a.txt


But it didn't work. How to do it correctly?

Answer
  1. perl -i.bak -pe "s/\n//" a.txt

I.e. just change \r\n to \n for the \r\n is automatically converted to \n on Windows as it was explained by ikegami.


  1. perl -i.bak -0777 -pe "s/^(function.*?\n)!/\1\t!/gm" a.txt

The main point here is that you need to read the entire file contents into a single string in order to do cross-line matches. -0777 parameter instructs Perl to do so (alternatively you may set $/ to a string from within Perl script).

Comments