使用 sed - 如何在第一次出现变量后替换行中第一次出现的字符串
Using sed - how to replace the first occurrence of a string on the line after the first occurrence of a variable
我在使用 sed 将变量用作搜索字符串时遇到了一些分层问题 AND 跨多行执行此操作。我可以做其中之一,但不能同时做。我正在处理一个看起来像这样的 xml 文件。
<tag property="search1">
string
</tag>
<tag property="search2">
string
</tag>
<tag property="search3">
string
</tag>
我正在尝试使用脚本依次将“string”替换为另一个值,具体取决于它前面一行中“search”字符串的编号。该脚本会增加一个计数器来执行此操作。
如果“$n”已知,我可以在“search$n”之后查找并替换“string”:
$ sed '$!N;/search2/ s/\string/foo/;P;D' test
<tag property="search1">
string
</tag>
<tag property="search2">
foo
</tag>
<tag property="search3">
string
</tag>
而且我可以根据变量搜索替换字符串:
$ n=2
$ sed "/search$n/ s/search/foo/" test
<tag property="search1">
string
</tag>
<tag property="foo2">
string
</tag>
<tag property="search3">
string
</tag>
但我一直没弄清楚如何将两者结合起来:
$ sed '$!N;/search$n/ s/\string/foo/;P;D' test
以上命令有效;因为它不会抛出错误,但它不会解析变量 - 我试过转义它,并将它放在双引号或单引号中并转义那些。允许我在 sed 中解析多行的参数似乎需要单引号,而在搜索字段中读取变量需要双引号...
我正在 OSX 并使用 gnu-sed。以下是我尝试过的其他一些方法:
sed "/search$n/,+1s/string/foo/" test
sed '/search$n/,+1s/string/foo/' test
sed "/search$n/,+1s s/string/foo/" test
sed '/search$n/,+1 s/string/foo/' test
sed '' -e '/search$n/ {' -e 'n; s/string/foo/' -e '}' test
sed '' -e '/search$n/ {' -e 'n; s/.*/foo/' -e '}' test
sed '/search$n/!b;n;c/foo/' test
sed '' -e '/search$n/!b;n;string' test
sed '' -e "/search$n/ {' -e 'n; s/string/foo/' -e '}" test
sed '' -e "/search$n/ {' -e 'n; s/.*/foo/g' -e '}" test
sed '' -e "/search$n/ s/string/foo/" test
sed -e "/search$n/ s/string/foo/" test
sed "/search$n/ s/string/foo/" test
您需要声明 n=2
(而不是 i=2
),然后使用双引号允许变量扩展。
但是,您需要注意 Bash 所特有的 $
和 !
。
您可以使用
n=2
sed '$!'"N;/search$n/ s/string/foo/;P;D" test
输出:
<tag property="search1">
string
</tag>
<tag property="search2">
foo
</tag>
<tag property="search3">
string
</tag>
'$!'"N;/search$n/ s/string/foo/;P;D"
是 $!
(不支持变量扩展)和 N;/search$n/ s/string/foo/;P;D
(支持变量扩展)的串联。
这可能适合您 (GNU sed):
n=2
sed '/search'"$n"'/{n;s/string/foo/}' file
将 n
设置为 2
。
在 search2
上匹配,打印当前行并获取下一行。
如果以下行包含 string
将 string
替换为 foo
。
有可能下一行不包含string
但包含search2
,在这种情况下:
sed ':a;/search'"$n"'/{n;s/string/foo/;Ta}' file
我在使用 sed 将变量用作搜索字符串时遇到了一些分层问题 AND 跨多行执行此操作。我可以做其中之一,但不能同时做。我正在处理一个看起来像这样的 xml 文件。
<tag property="search1">
string
</tag>
<tag property="search2">
string
</tag>
<tag property="search3">
string
</tag>
我正在尝试使用脚本依次将“string”替换为另一个值,具体取决于它前面一行中“search”字符串的编号。该脚本会增加一个计数器来执行此操作。
如果“$n”已知,我可以在“search$n”之后查找并替换“string”:
$ sed '$!N;/search2/ s/\string/foo/;P;D' test
<tag property="search1">
string
</tag>
<tag property="search2">
foo
</tag>
<tag property="search3">
string
</tag>
而且我可以根据变量搜索替换字符串:
$ n=2
$ sed "/search$n/ s/search/foo/" test
<tag property="search1">
string
</tag>
<tag property="foo2">
string
</tag>
<tag property="search3">
string
</tag>
但我一直没弄清楚如何将两者结合起来:
$ sed '$!N;/search$n/ s/\string/foo/;P;D' test
以上命令有效;因为它不会抛出错误,但它不会解析变量 - 我试过转义它,并将它放在双引号或单引号中并转义那些。允许我在 sed 中解析多行的参数似乎需要单引号,而在搜索字段中读取变量需要双引号...
我正在 OSX 并使用 gnu-sed。以下是我尝试过的其他一些方法:
sed "/search$n/,+1s/string/foo/" test
sed '/search$n/,+1s/string/foo/' test
sed "/search$n/,+1s s/string/foo/" test
sed '/search$n/,+1 s/string/foo/' test
sed '' -e '/search$n/ {' -e 'n; s/string/foo/' -e '}' test
sed '' -e '/search$n/ {' -e 'n; s/.*/foo/' -e '}' test
sed '/search$n/!b;n;c/foo/' test
sed '' -e '/search$n/!b;n;string' test
sed '' -e "/search$n/ {' -e 'n; s/string/foo/' -e '}" test
sed '' -e "/search$n/ {' -e 'n; s/.*/foo/g' -e '}" test
sed '' -e "/search$n/ s/string/foo/" test
sed -e "/search$n/ s/string/foo/" test
sed "/search$n/ s/string/foo/" test
您需要声明 n=2
(而不是 i=2
),然后使用双引号允许变量扩展。
但是,您需要注意 Bash 所特有的 $
和 !
。
您可以使用
n=2
sed '$!'"N;/search$n/ s/string/foo/;P;D" test
输出:
<tag property="search1">
string
</tag>
<tag property="search2">
foo
</tag>
<tag property="search3">
string
</tag>
'$!'"N;/search$n/ s/string/foo/;P;D"
是 $!
(不支持变量扩展)和 N;/search$n/ s/string/foo/;P;D
(支持变量扩展)的串联。
这可能适合您 (GNU sed):
n=2
sed '/search'"$n"'/{n;s/string/foo/}' file
将 n
设置为 2
。
在 search2
上匹配,打印当前行并获取下一行。
如果以下行包含 string
将 string
替换为 foo
。
有可能下一行不包含string
但包含search2
,在这种情况下:
sed ':a;/search'"$n"'/{n;s/string/foo/;Ta}' file