开发者

sed multiline range match

I'm trying to do a multi-line sed range match. What I mean by this is that the beginning of the range is itself multiple lin开发者_运维百科es. The source looks like this

<filter-mapping>
        <filter-name>Cache Filter - Resource</filter-name>
        <url-pattern>*.css</url-pattern>
</filter-mapping>
<filter-mapping>
        <filter-name>Cache Filter - Resource</filter-name>
        <url-pattern>*.html</url-pattern>
</filter-mapping>
<filter-mapping>
        <filter-name>Cache Filter - Resource</filter-name>
        <url-pattern>*.js</url-pattern>
</filter-mapping>
<filter-mapping>
        <filter-name>Cache Filter - Resource JSP</filter-name>
        <url-pattern>*.jsp</url-pattern>
</filter-mapping>

And the only uniquely identifying segment to start the range is the entire first three lines, and the end of the range is identified by the entire last two lines.

Is there a way to specify a multiline pattern to begin a range match?


Alright, so I went with tchrist's solution and used perl instead. Here's what my regex looked like (in this example, I'm commenting out the xml). I'm also doing an inline replacement of the file.

perl -0777 -pi -e 's|([\t ]*<filter-mapping>\s*<filter-name>Cache Filter - Resource</filter-name>\s*<url-pattern>\*\.css[^\0]*<filter-name>Cache Filter - Resource JSP</filter-name>\s*<url-pattern>\*\.jsp</url-pattern>\s*</filter-mapping>)|<!-- \1 -->|g' inputfile


The best sed tutorial online covers this topic: http://www.grymoire.com/Unix/Sed.html#uh-51

If you're fairly new to sed, you probably want to start further up the page, like here: http://www.grymoire.com/Unix/Sed.html#uh-47


Using the Pearl approach (thanks! that was useful), I was only able to perform a multi-line match with the s modifier.

Since I'm using this for parameter replacement in Tomcat's web.xml, I place a copy of my bash script for anyone interested (comments are welcome).

#!/bin/bash
if [[ -z "$3" ]] ; then
        echo "Sets a Tomcat web.xml parameter with a new value"
        echo "SINTAX: $0 PARAM_NAME NEW_VALUE FILE"
        exit 1
fi

PARAM_NAME="$1"
NEW_VALUE="$2"
FILE="$3"

perl -0777 -pi -e  "s|(<param-name>${PARAM_NAME}</param-name>.*?<param-value>).*?(</param-value>)|\${1}${NEW_VALUE}\${2}|s" ${FILE}

Note: the part \${1} is done this way because ${NEW_VALUE} could be one or more digits and it would confuse perl.


Here is a processing using sed of multi-line:

sed ' /<filter-mapping>/,/<[/]filter-mapping>/{/filter-mapping/d}' FILE

This prints only the text between filter-maping

<filter-mapping>
        TEXT
</filter-mapping>

I did not understand quite precisely what you want to do ...


You had best do this either with perl -0777 -pe 's/.../.../', or else use a proper parser.

Do not use sed. Really.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜