Reputation: 95
I'm trying to parse the following multiline string (starting with ) and comment it out.
-->
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
<!-- A "Connector" using the shared thread pool-->
So I tried using the following:
perl -i.bak -pe 'BEGIN{undef $/;}
s/
\s+ #space at beginning of line
(<Connector\s+ #connector
port=\"8080\"\s+ #port
protocol=\"HTTP\/1\.1\" #protocol
\n #newline
\s+connectionTimeout=\"20000\"\n # space, connection timeout, then newline
\s+redirectPort=\"8443\" #redirect port
\/> # end of connector entry in file
) # end capture for $1
/
<!--$1-->
/msx
' server.xml
diff server.xml server.xml.bak
But the diff output shows nothing. Any idea what I'm missing here?
Upvotes: 1
Views: 63
Reputation: 1832
Don't use that BEGIN block. The normal way to slurp in a text file is to use the -0
switch. That sets the input record seperator to the null character. If there is any chance there are nulls in the file use -0777
.
If you know precisely what the search text is, you don't need anything as complicated as you wrote. Perl has that use case covered. The \Q \E
operator automatically quotes any possibly troublesome characters but still allows variable substitution to happen.
$foo = 'f.oo bar$'; print qr/\Q$foo\E/;
(?^:f\.oo\ bar\$)
$pattern = qr{\Q<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />\E};
$text =~ s/($pattern)/<!-- $1 -->/;
I see that you want to do it as a command line so it would be something like this.
perl -i.bak -lp0e '$pattern = qr{\Q<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />\E};
s/($pattern)/<!-- $1 -->/; ' FILE
The code you put will only execute once because there is only "one line" to the input.
If there is wiggle room in the amount of whitespace, you can do a dynamic substitution on the pattern itself.
$pattern = qq{\Q<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />\E};
# Translate runs of escaped whitspace into a single \s+
$pattern =~ s/(?:\\\s)+/\s+/g;
$text =~ s/($pattern)/<!-- $1 -->/;
HTH
Upvotes: 0
Reputation: 95
I think I figured it out.
perl -i.bak -pe 'BEGIN{undef $/;}
s/
--> #preceding line ends a comment, with newline at end
\s+ #space at beginning of line
(<Connector\s+ #connector
port=\"8080\"\s+ #port
protocol=\"HTTP\/1\.1\" #protocol
\s+connectionTimeout=\"20000\" # space, connection timeout, then newline
\s+redirectPort=\"8443\" #redirect port
\s+ #space
\/> # end of connector entry in file
) # end capture for $1
/
-->\n<!-- $1 -->
/msx
' server.xml
diff server.xml server.xml.bak
~
Upvotes: 2