<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
		>
<channel>
	<title>Comments on: sed and Multi-Line Search and Replace</title>
	<atom:link href="http://austinmatzko.com/2008/04/26/sed-multi-line-search-and-replace/feed/" rel="self" type="application/rss+xml" />
	<link>http://austinmatzko.com/2008/04/26/sed-multi-line-search-and-replace/</link>
	<description>A blog about philosophy, Christianity, web development and whatever else I feel like writing about.</description>
	<lastBuildDate>Tue, 31 Aug 2010 10:13:04 +0000</lastBuildDate>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1-alpha</generator>
	<item>
		<title>By: Perl regex not matching across multiple lines despite ms flags</title>
		<link>http://austinmatzko.com/2008/04/26/sed-multi-line-search-and-replace/comment-page-1/#comment-212747</link>
		<dc:creator>Perl regex not matching across multiple lines despite ms flags</dc:creator>
		<pubDate>Tue, 17 Aug 2010 00:29:07 +0000</pubDate>
		<guid isPermaLink="false">http://www.ilfilosofo.com/?p=458#comment-212747</guid>
		<description>[...] sed -n &#039; # if the first line copy the pattern to the hold buffer 1h # if not the first line then append the pattern to the hold buffer 1!H # if the last line then ... $ { # copy from the hold to the pattern buffer g # do the search and replace s/([[:alnum:]_]+):[[:blank:]]?function[[:blank:]]?1?(([[:alnum:]_[:blank:],]*)) {(([^}])*)}/1: (function 1(2) {3})/g # print p } &#039; file reference: http://austinmatzko.com/2008/04/26/s...h-and-replace/ [...]</description>
		<content:encoded><![CDATA[<p>[...] sed -n &#039; # if the first line copy the pattern to the hold buffer 1h # if not the first line then append the pattern to the hold buffer 1!H # if the last line then &#8230; $ { # copy from the hold to the pattern buffer g # do the search and replace s/([[:alnum:]_]+):[[:blank:]]?function[[:blank:]]?1?(([[:alnum:]_[:blank:],]*)) {(([^}])*)}/1: (function 1(2) {3})/g # print p } &#039; file reference: <a href="http://austinmatzko.com/2008/04/26/s...h-and-replace/" rel="nofollow">http://austinmatzko.com/2008/04/26/s&#8230;h-and-replace/</a> [...]</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Alex</title>
		<link>http://austinmatzko.com/2008/04/26/sed-multi-line-search-and-replace/comment-page-1/#comment-212742</link>
		<dc:creator>Alex</dc:creator>
		<pubDate>Mon, 16 Aug 2010 05:51:19 +0000</pubDate>
		<guid isPermaLink="false">http://www.ilfilosofo.com/?p=458#comment-212742</guid>
		<description>the line 

&lt;code&gt;/&lt;h2.*/No title here/g&lt;/code&gt;

doesn&#039;t the forward slash in the closing h2 tag confuse sed since you also use forward slash as your separator</description>
		<content:encoded><![CDATA[<p>the line </p>
<p><code>/&lt;h2.*/No title here/g</code></p>
<p>doesn&#8217;t the forward slash in the closing h2 tag confuse sed since you also use forward slash as your separator</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: SED behavior</title>
		<link>http://austinmatzko.com/2008/04/26/sed-multi-line-search-and-replace/comment-page-1/#comment-212544</link>
		<dc:creator>SED behavior</dc:creator>
		<pubDate>Fri, 14 May 2010 13:46:24 +0000</pubDate>
		<guid isPermaLink="false">http://www.ilfilosofo.com/?p=458#comment-212544</guid>
		<description>[...] for e.g.  text=&quot;Title Linux kernel UUID=asdlkkjaljdhakjsdhakjsd blabla init blabla &quot; (I was inspired here) - but I found problems. I had to replace new line characters on enf of lines. So in real it is not [...]</description>
		<content:encoded><![CDATA[<p>[...] for e.g.  text=&quot;Title Linux kernel UUID=asdlkkjaljdhakjsdhakjsd blabla init blabla &quot; (I was inspired here) &#8211; but I found problems. I had to replace new line characters on enf of lines. So in real it is not [...]</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: sed - testing multiline search and replace</title>
		<link>http://austinmatzko.com/2008/04/26/sed-multi-line-search-and-replace/comment-page-1/#comment-212510</link>
		<dc:creator>sed - testing multiline search and replace</dc:creator>
		<pubDate>Mon, 10 May 2010 18:11:08 +0000</pubDate>
		<guid isPermaLink="false">http://www.ilfilosofo.com/?p=458#comment-212510</guid>
		<description>[...] = &quot;#002285&quot;; netseer_network_id = 1040;    [Log in to get rid of this advertisement]  Hi, I found a example how to do multiline search and replace. I try to make this working to my needs but with no success [...]</description>
		<content:encoded><![CDATA[<p>[...] = &quot;#002285&quot;; netseer_network_id = 1040;    [Log in to get rid of this advertisement]  Hi, I found a example how to do multiline search and replace. I try to make this working to my needs but with no success [...]</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: LDIF-Dateien zur Konfiguration von OpenLDAP bequem erzeugen &#171; Abraxas</title>
		<link>http://austinmatzko.com/2008/04/26/sed-multi-line-search-and-replace/comment-page-1/#comment-212291</link>
		<dc:creator>LDIF-Dateien zur Konfiguration von OpenLDAP bequem erzeugen &#171; Abraxas</dc:creator>
		<pubDate>Sun, 28 Mar 2010 10:22:57 +0000</pubDate>
		<guid isPermaLink="false">http://www.ilfilosofo.com/?p=458#comment-212291</guid>
		<description>[...] Ersetzen von Text über mehrere Zeilen hinweg mit sed [...]</description>
		<content:encoded><![CDATA[<p>[...] Ersetzen von Text über mehrere Zeilen hinweg mit sed [...]</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Frank</title>
		<link>http://austinmatzko.com/2008/04/26/sed-multi-line-search-and-replace/comment-page-1/#comment-212035</link>
		<dc:creator>Frank</dc:creator>
		<pubDate>Mon, 22 Feb 2010 20:04:22 +0000</pubDate>
		<guid isPermaLink="false">http://www.ilfilosofo.com/?p=458#comment-212035</guid>
		<description>Never mind.  I figured it out.  Although I can&#039;t show the final code because I can&#039;t figure out how to escape all the chars.  Basically, you have to escape the backslash on the closing h2 tag.</description>
		<content:encoded><![CDATA[<p>Never mind.  I figured it out.  Although I can&#8217;t show the final code because I can&#8217;t figure out how to escape all the chars.  Basically, you have to escape the backslash on the closing h2 tag.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Frank</title>
		<link>http://austinmatzko.com/2008/04/26/sed-multi-line-search-and-replace/comment-page-1/#comment-212034</link>
		<dc:creator>Frank</dc:creator>
		<pubDate>Mon, 22 Feb 2010 19:55:15 +0000</pubDate>
		<guid isPermaLink="false">http://www.ilfilosofo.com/?p=458#comment-212034</guid>
		<description>When trying to replicate this example by running the command suggested:
&lt;code&gt;sed -n &#039;1h;1!H;${;g;s/&lt;h2.*/No title here/g;p;}&#039; sample.php&lt;/code&gt;

I get the following error:
&lt;code&gt;sed: -e expression #1, char 26: unknown option to `s&#039;&lt;/code&gt;</description>
		<content:encoded><![CDATA[<p>When trying to replicate this example by running the command suggested:<br />
<code>sed -n '1h;1!H;${;g;s/&lt;h2.*/No title here/g;p;}' sample.php</code></p>
<p>I get the following error:<br />
<code>sed: -e expression #1, char 26: unknown option to `s'</code></p>
]]></content:encoded>
	</item>
	<item>
		<title>By: bun</title>
		<link>http://austinmatzko.com/2008/04/26/sed-multi-line-search-and-replace/comment-page-1/#comment-210741</link>
		<dc:creator>bun</dc:creator>
		<pubDate>Sun, 11 Oct 2009 03:52:27 +0000</pubDate>
		<guid isPermaLink="false">http://www.ilfilosofo.com/?p=458#comment-210741</guid>
		<description>$ sorry, the sed part didn&#039;t come right
&lt;blockquote&gt;&lt;code&gt;sed -n ${OPT_I}$SUFFIX &#039;
/&lt; *&#039;&quot;$START&quot;&#039;&gt;/b proc
p
b

:proc
n
s&#124;&lt; *&#039;&quot;$END&quot;&#039; *&gt;&#124;&#039;&quot;$TEXT&quot;&#039;&#124;p
t
b proc
&#039; $FILES
&lt;/code&gt;&lt;/blockquote&gt;</description>
		<content:encoded><![CDATA[<p>$ sorry, the sed part didn&#8217;t come right</p>
<blockquote><p><code>sed -n ${OPT_I}$SUFFIX '<br />
/&lt; *'"$START"'&gt;/b proc<br />
p<br />
b</code></p>
<p>:proc<br />
n<br />
s|&lt; *'"$END"' *&gt;|'"$TEXT"'|p<br />
t<br />
b proc<br />
' $FILES<br />
</p></blockquote>
]]></content:encoded>
	</item>
	<item>
		<title>By: bun</title>
		<link>http://austinmatzko.com/2008/04/26/sed-multi-line-search-and-replace/comment-page-1/#comment-210740</link>
		<dc:creator>bun</dc:creator>
		<pubDate>Sun, 11 Oct 2009 03:47:18 +0000</pubDate>
		<guid isPermaLink="false">http://www.ilfilosofo.com/?p=458#comment-210740</guid>
		<description>$ gee, i was testing my last posted sc, bugs came out:
- it doesn&#039;t ignore spacing within &lt;&gt; (fixed)
- it also modifies more specific tags if given a more general one of that tag, ex: given %lt;h1&gt; it also modifies &lt;h1 ...&gt;

$ &#039;f&#039; opt is added, if &#039;f&#039; used, it performs fixed match for the given tag: &lt;h1&gt; only matches &lt;h1&gt;), while if no &#039;f&#039; &lt;h1&gt; matches &lt;h1 ...&gt;

$ it still ignores tag nesting (gonna work on this one)

&lt;blockquote&gt;&lt;code&gt;#! /bin/bash

set -o xtrace

usage(){
echo &quot;usage: $0 [i][b SUFFIX][f] TAG TEXT [FILES...]&quot;
	exit 1
}

FIXED=0

while getopts &quot;:ib:f&quot; OPT; do
case $OPT in
i)	OPT_I=-i
	unset SUFFIX
;;
b)	OPT_I=-i
	SUFFIX=&quot;$OPTARG&quot;
;;
f)
	FIXED=1
;;
*)	usage
;;
esac
done

shift $(($OPTIND-1))

# only TAG &amp; TEXT must be present in invocation line
if(($# &lt; 2)); then
	usage
fi

# there must be no leading / trailing space around the tag given in cmd-line
START=$1

if [ &quot;${START:0:1}&quot; == &quot; &lt; &quot; ]; then
	START=${START:1}
fi
if [ &quot;${START:${#START}-1}&quot; == &quot; &gt; &quot; ]; then
	START=${START:0:${#START}-1}
fi

# is there syntax / tool to do this cleanly? for substr based on char
END=/${START%% *}	#get only up to the 1st space

TEXT=$2
# reformat &amp; and \ to be edible for sed &#039;s&#039; cmd
TEXT=&quot;${TEXT//\\/\\\\}&quot;
TEXT=&quot;${TEXT/&amp;/\&amp;}&quot;

shift 2

# preserve *nix philosophy of &#039;small tool&#039; by expecting input of files from stdin &amp; defaultly sending output to stdout
if(($#==0)); then
	while read F; do
		FILES=&quot;${FILES} $F&quot;
	done
else
	FILES=$*
fi

if(($FIXED==0)); then
START=$START&#039;.*&#039;
else
START=$START&#039; *&#039;
fi

echo &quot;$START&quot;

sed -n ${OPT_I}$SUFFIX &#039;
/[ *&#039;&quot;$START&quot;&#039;]/b proc
p;b

:proc
n
s&#124;&#124;&#039;&quot;$TEXT&quot;&#039;&#124;p
t
b proc
&#039; $FILES
&lt;/code&gt;&lt;/blockquote&gt;

$ btw, i was actually found this page when googled &quot;multiline sed&quot;. i was learning sed &amp; got stuck with gnu ext of multi-line M for &#039;s&#039; cmd / pattern matching. gnu doc only defines it, i need examples, anyone?</description>
		<content:encoded><![CDATA[<p>$ gee, i was testing my last posted sc, bugs came out:<br />
- it doesn&#8217;t ignore spacing within &lt;&gt; (fixed)<br />
- it also modifies more specific tags if given a more general one of that tag, ex: given %lt;h1&gt; it also modifies &lt;h1 &#8230;&gt;</p>
<p>$ &#8216;f&#8217; opt is added, if &#8216;f&#8217; used, it performs fixed match for the given tag: &lt;h1&gt; only matches &lt;h1&gt;), while if no &#8216;f&#8217; &lt;h1&gt; matches &lt;h1 &#8230;&gt;</p>
<p>$ it still ignores tag nesting (gonna work on this one)</p>
<blockquote><p><code>#! /bin/bash</code></p>
<p>set -o xtrace</p>
<p>usage(){<br />
echo "usage: $0 [i][b SUFFIX][f] TAG TEXT [FILES...]"<br />
	exit 1<br />
}</p>
<p>FIXED=0</p>
<p>while getopts ":ib:f" OPT; do<br />
case $OPT in<br />
i)	OPT_I=-i<br />
	unset SUFFIX<br />
;;<br />
b)	OPT_I=-i<br />
	SUFFIX="$OPTARG"<br />
;;<br />
f)<br />
	FIXED=1<br />
;;<br />
*)	usage<br />
;;<br />
esac<br />
done</p>
<p>shift $(($OPTIND-1))</p>
<p># only TAG &amp; TEXT must be present in invocation line<br />
if(($# &lt; 2)); then<br />
	usage<br />
fi</p>
<p># there must be no leading / trailing space around the tag given in cmd-line<br />
START=$1</p>
<p>if [ &quot;${START:0:1}&quot; == &quot; &lt; &quot; ]; then<br />
	START=${START:1}<br />
fi<br />
if [ &quot;${START:${#START}-1}&quot; == &quot; &gt; &quot; ]; then<br />
	START=${START:0:${#START}-1}<br />
fi</p>
<p># is there syntax / tool to do this cleanly? for substr based on char<br />
END=/${START%% *}	#get only up to the 1st space</p>
<p>TEXT=$2<br />
# reformat &amp; and \ to be edible for sed &#039;s&#039; cmd<br />
TEXT=&quot;${TEXT//\\/\\\\}&quot;<br />
TEXT=&quot;${TEXT/&amp;/\&amp;}&quot;</p>
<p>shift 2</p>
<p># preserve *nix philosophy of &#039;small tool&#039; by expecting input of files from stdin &amp; defaultly sending output to stdout<br />
if(($#==0)); then<br />
	while read F; do<br />
		FILES=&quot;${FILES} $F&quot;<br />
	done<br />
else<br />
	FILES=$*<br />
fi</p>
<p>if(($FIXED==0)); then<br />
START=$START&#039;.*&#039;<br />
else<br />
START=$START&#039; *&#039;<br />
fi</p>
<p>echo &quot;$START&quot;</p>
<p>sed -n ${OPT_I}$SUFFIX &#039;<br />
/[ *&#039;&quot;$START&quot;&#039;]/b proc<br />
p;b</p>
<p>:proc<br />
n<br />
s||'"$TEXT"'|p<br />
t<br />
b proc<br />
' $FILES<br />
</p></blockquote>
<p>$ btw, i was actually found this page when googled &#8220;multiline sed&#8221;. i was learning sed &amp; got stuck with gnu ext of multi-line M for &#8216;s&#8217; cmd / pattern matching. gnu doc only defines it, i need examples, anyone?</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: bun</title>
		<link>http://austinmatzko.com/2008/04/26/sed-multi-line-search-and-replace/comment-page-1/#comment-210649</link>
		<dc:creator>bun</dc:creator>
		<pubDate>Fri, 09 Oct 2009 12:41:23 +0000</pubDate>
		<guid isPermaLink="false">http://www.ilfilosofo.com/?p=458#comment-210649</guid>
		<description>$ things i notice:
1. (i&#039;m not sure about this since i didn&#039;t try your sc). it looks like there is a problem in the invocation line:
&lt;code&gt;grep -rl &#039;&lt;h2&#039; * &#124; while read i; do
sedml $i &quot;s/&lt;h2.*/No title here/g&quot; $i.tmp
done
&lt;/code&gt;

- in the arg for the sed &#039;s&#039; cmd, isn&#039;t that the / in  will be taken by sed as the &#039;s&#039; delimiter? yes, it can be simply changed to another char. but what bothers me (maybe it&#039;s just me since i barely know regex) is that the sc user must be a bit familiar with regex &amp; moreover with sed &#039;s&#039; cmd

- also, the &#039;s&#039; cmd regex will go across multiple  since .* match longest pattern

2. as u said: for each input file, the hold buf contains all the complete input, meaning more text more mem consumed, worse for other app, more danger for sed to be killed

3. (i&#039;m assuming you&#039;re concern about efficiency since u gave 2nd try to the problem for it)

- for each file found by &#039;grep&#039; containing at least 1 of the searched html tag (), it brings up a subsh which in turn brings up sed, meaning a pair of subsh &amp; sed if started &amp; ended for each input file. 

- it execs grep in this sh while it also starts a subsh to perform &#039;while read i...&#039;. inside the while loop, the subsh will starts another subsh (due to #!/bin/sh), then the last created subsh starts sed, &amp; repetition begins

- yes, how process is treated after it exits (particularly whether the core image is still in the mem / not) is kernel-dependent. but 1 thing for sure is that single invocation of an app to deal with multiple input files will always be more efficient than a single invocation of it for each input file, even for *nix where its philosophy of small tools requires low rsc cost for process creation

$ the idea basically:
sed -n &#039;
/&lt;h2/b proc
p; b

:proc
n
s//no title here/p
t
b proc
&#039; INPUT_FILE...

$ some minimum enhancements i can think of:
1. for the searched html tag:
- it&#039;s variable
- user doesn&#039;t need to know about regex
- the tag can be specific by specifying its attribute

&gt; ex:
input: 
- only replace that particular h1, other h1 with diff title including ones that don&#039;t have title isn&#039;t affected. also that the input need not be full. the previous input can be like  in the html code
- since all paired html tag looks like: start mark &lt;TAG... and end mark &lt;/TAG..., user need only input the start mark, this also eliminate forcing user to know about regex

2. the replacement text can be any char including ones that are special in sed&#039;s eye: &amp; \N, the user don&#039;t need to know about it

3. for sed to be invoked only 1 once for multiple input files while retaining the ability to save the original file / editing in place &amp; without manual tmp file, there is only 1 way: use -i[SUFFIX]

$ here&#039;s the sc, my apology for its ugliness, i don&#039;t know much about *nix:

#! /bin/bash

usage(){
	echo &quot;usage: $0 [i][b SUFFIX] TAG TEXT [FILES...]&quot;
	exit 1
}

while getopts &quot;:ib:&quot; OPT; do
case $OPT in
i)	OPT_I=-i
	unset SUFFIX
;;
b)	OPT_I=-i
	SUFFIX=&quot;$OPTARG&quot;
;;
*)	usage
;;
esac
done

shift $(($OPTIND-1))

# only TAG &amp; TEXT must be present in invocation line
if(($#, so that no need to give all tag&#039;s attrs
if [ &quot;${START:${#START}-1}&quot; == &quot;&gt;&quot; ]; then
START=${START:0:${#START}-1}
fi

# is there syntax / tool to do this cleanly? for substr based on char
END=${START%% *}	#get only up to the 1st space
END=${END:0:1}/${END:1}

TEXT=$2
# reformat &amp; and \ to be edible for sed &#039;s&#039; cmd
TEXT=&quot;${TEXT//\\/\\\\}&quot;
TEXT=&quot;${TEXT/&amp;/\&amp;}&quot;
#TEXT=&quot;$(echo &quot;$TEXT&quot; &#124; sed -r &#039;s/\\/\\\\/g;&#039;)&quot;

shift 2

# preserve *nix philosophy of &#039;small tool&#039; by expecting input of files from stdin &amp; defaultly sending output to stdout
if(($#==0)); then
	while read F; do
		FILES=&quot;${FILES} $F&quot;
	done
else
	FILES=$*
fi

sed -n ${OPT_I}$SUFFIX &#039;
/&#039;&quot;$START&quot;&#039;/b proc
p
b

:proc
n
s&#124;.*&#039;&quot;$END&quot;&#039;.*&#124;&#039;&quot;$TEXT&quot;&#039;&#124;p
t	#sc goes to eof if matching closing tag is found
b proc
&#039; $FILES

$ i&#039;m sure there&#039;re lots more than can be done to it without breaking unix philosophy, such as its ability to change a tag at a particular nested lv, but i won&#039;t know since i&#039;m not a web dev</description>
		<content:encoded><![CDATA[<p>$ things i notice:<br />
1. (i&#8217;m not sure about this since i didn&#8217;t try your sc). it looks like there is a problem in the invocation line:<br />
<code>grep -rl '&lt;h2&#039; * | while read i; do<br />
sedml $i &quot;s/&lt;h2.*/No title here/g" $i.tmp<br />
done<br />
</code></p>
<p>- in the arg for the sed &#8216;s&#8217; cmd, isn&#8217;t that the / in  will be taken by sed as the &#8216;s&#8217; delimiter? yes, it can be simply changed to another char. but what bothers me (maybe it&#8217;s just me since i barely know regex) is that the sc user must be a bit familiar with regex &amp; moreover with sed &#8216;s&#8217; cmd</p>
<p>- also, the &#8216;s&#8217; cmd regex will go across multiple  since .* match longest pattern</p>
<p>2. as u said: for each input file, the hold buf contains all the complete input, meaning more text more mem consumed, worse for other app, more danger for sed to be killed</p>
<p>3. (i&#8217;m assuming you&#8217;re concern about efficiency since u gave 2nd try to the problem for it)</p>
<p>- for each file found by &#8216;grep&#8217; containing at least 1 of the searched html tag (), it brings up a subsh which in turn brings up sed, meaning a pair of subsh &amp; sed if started &amp; ended for each input file. </p>
<p>- it execs grep in this sh while it also starts a subsh to perform &#8216;while read i&#8230;&#8217;. inside the while loop, the subsh will starts another subsh (due to #!/bin/sh), then the last created subsh starts sed, &amp; repetition begins</p>
<p>- yes, how process is treated after it exits (particularly whether the core image is still in the mem / not) is kernel-dependent. but 1 thing for sure is that single invocation of an app to deal with multiple input files will always be more efficient than a single invocation of it for each input file, even for *nix where its philosophy of small tools requires low rsc cost for process creation</p>
<p>$ the idea basically:<br />
sed -n &#8216;<br />
/&lt;h2/b proc<br />
p; b</p>
<p>:proc<br />
n<br />
s//no title here/p<br />
t<br />
b proc<br />
&#8216; INPUT_FILE&#8230;</p>
<p>$ some minimum enhancements i can think of:<br />
1. for the searched html tag:<br />
- it&#8217;s variable<br />
- user doesn&#8217;t need to know about regex<br />
- the tag can be specific by specifying its attribute</p>
<p>&gt; ex:<br />
input:<br />
- only replace that particular h1, other h1 with diff title including ones that don&#8217;t have title isn&#8217;t affected. also that the input need not be full. the previous input can be like  in the html code<br />
- since all paired html tag looks like: start mark &lt;TAG&#8230; and end mark &lt;/TAG&#8230;, user need only input the start mark, this also eliminate forcing user to know about regex</p>
<p>2. the replacement text can be any char including ones that are special in sed&#039;s eye: &amp; \N, the user don&#039;t need to know about it</p>
<p>3. for sed to be invoked only 1 once for multiple input files while retaining the ability to save the original file / editing in place &amp; without manual tmp file, there is only 1 way: use -i[SUFFIX]</p>
<p>$ here&#039;s the sc, my apology for its ugliness, i don&#039;t know much about *nix:</p>
<p>#! /bin/bash</p>
<p>usage(){<br />
	echo &quot;usage: $0 [i][b SUFFIX] TAG TEXT [FILES...]&quot;<br />
	exit 1<br />
}</p>
<p>while getopts &quot;:ib:&quot; OPT; do<br />
case $OPT in<br />
i)	OPT_I=-i<br />
	unset SUFFIX<br />
;;<br />
b)	OPT_I=-i<br />
	SUFFIX=&quot;$OPTARG&quot;<br />
;;<br />
*)	usage<br />
;;<br />
esac<br />
done</p>
<p>shift $(($OPTIND-1))</p>
<p># only TAG &amp; TEXT must be present in invocation line<br />
if(($#, so that no need to give all tag&#8217;s attrs<br />
if [ "${START:${#START}-1}" == "&gt;" ]; then<br />
START=${START:0:${#START}-1}<br />
fi</p>
<p># is there syntax / tool to do this cleanly? for substr based on char<br />
END=${START%% *}	#get only up to the 1st space<br />
END=${END:0:1}/${END:1}</p>
<p>TEXT=$2<br />
# reformat &amp; and \ to be edible for sed &#8216;s&#8217; cmd<br />
TEXT=&#8221;${TEXT//\\/\\\\}&#8221;<br />
TEXT=&#8221;${TEXT/&amp;/\&amp;}&#8221;<br />
#TEXT=&#8221;$(echo &#8220;$TEXT&#8221; | sed -r &#8216;s/\\/\\\\/g;&#8217;)&#8221;</p>
<p>shift 2</p>
<p># preserve *nix philosophy of &#8216;small tool&#8217; by expecting input of files from stdin &amp; defaultly sending output to stdout<br />
if(($#==0)); then<br />
	while read F; do<br />
		FILES=&#8221;${FILES} $F&#8221;<br />
	done<br />
else<br />
	FILES=$*<br />
fi</p>
<p>sed -n ${OPT_I}$SUFFIX &#8216;<br />
/&#8217;&#8221;$START&#8221;&#8216;/b proc<br />
p<br />
b</p>
<p>:proc<br />
n<br />
s|.*&#8217;&#8221;$END&#8221;&#8216;.*|&#8217;&#8221;$TEXT&#8221;&#8216;|p<br />
t	#sc goes to eof if matching closing tag is found<br />
b proc<br />
&#8216; $FILES</p>
<p>$ i&#8217;m sure there&#8217;re lots more than can be done to it without breaking unix philosophy, such as its ability to change a tag at a particular nested lv, but i won&#8217;t know since i&#8217;m not a web dev</p>
]]></content:encoded>
	</item>
</channel>
</rss>
