在我的文件中,我需要交换以下所有实例的位置:
grep 'search string'
和
sed '/string of text/,/string of text/{//!d}'
在 VI 中,我尝试了正则表达式,但没有成功 - 它说了一些关于尾随字符的内容。
:%s/grep 'search string'/sed '/string of text/,/string of text/{//!d}'/g
我还尝试在文件外使用 sed: 表示未找到事件
sed -i 's/grep 'search string'/sed '/search string/,/search string/{//!d}'/g' filename.
我做错了什么以及如何让它发挥作用?我有太多需要更改的实例,并且手动执行此操作不是一个选择。
我想更改这行代码:
succ_1st=`grep 'resulted in successful answer' $path_tmp/named.stats.tmp | sed '/localhost.localdomain/,/testdns.net/{//!d}' | awk '{ print $1 }' | grep -m1 ''`
对此:
succ_1st=`sed '/localhost.localdomain/,/testdns.net/{//!d}' $path_tmp/named.stats.tmp | grep 'resulted in successful answer' | awk '{ print $1 }' | grep -m1 ''`
顺便说一句,这些是脚本中的代码行
答案1
对于你的第一个问题
为了使该命令起作用,更改分隔符会有所帮助。此外,sed 命令中的单引号需要正确转义以保护它们免受 shell 的影响:
sed 's|grep '\''search string'\''|sed '\''/search string/,/search string/{//!d}'\''|g' file
例如,使用此测试文件:
$ cat file
grep 'search string'
上述命令产生:
$ sed 's|grep '\''search string'\''|sed '\''/search string/,/search string/{//!d}'\''|g' file
sed '/search string/,/search string/{//!d}'
要更改文件,请添加标志-i
:
sed -i 's|grep '\''search string'\''|sed '\''/search string/,/search string/{//!d}'\''|g' file
对于你的第二个问题
sed -r 's/(grep[^$]*)([$][^|]*)[|] (sed[^|]*)/\3\2| \1/' filename
例如,考虑这个测试文件:
$ cat filename
succ_1st=`grep 'resulted in successful answer' $path_tmp/named.stats.tmp | sed '/localhost.localdomain/,/testdns.net/{//!d}' | awk '{ print $1 }' | grep -m1 ''`
该命令产生:
$ sed -r 's/(grep[^$]*)([$][^|]*)[|] (sed[^|]*)/\3\2| \1/' filename
succ_1st=`sed '/localhost.localdomain/,/testdns.net/{//!d}' $path_tmp/named.stats.tmp | grep 'resulted in successful answer' | awk '{ print $1 }' | grep -m1 ''`
要就地更改文件,请添加标志-i
:
sed -ir 's/(grep[^$]*)([$][^|]*)[|] (sed[^|]*)/\3\2| \1/' filename
Vi 命令
上面的第一个命令可以在 vim 中执行:
%s/grep 'search string'/sed '\/search string\/,\/search string\/{\/\/!d}'/g
交换命令可以在 vim 中执行:
%s/\v(grep[^$]*)([$][^|]*)[|] (sed[^|]*)/\3\2| \1/
答案2
不是 sed,主要是 bash:
string=$(cat <<'END'
succ_1st=`grep 'resulted in successful answer' $path_tmp/named.stats.tmp | sed '/localhost.localdomain/,/testdns.net/{//!d}' | awk '{ print $1 }' | grep -m1 ''`
END
)
var=$(cut -d'`' -f1 <<<"$string")
code=$(cut -d'`' -f2 <<<"$string")
IFS='|' read -ra commands <<<"$code"
filename=$( set -f; eval set -- "${commands[0]}"; echo ${!#} ) # danger
tmp=${commands[0]//${filename//\//\\\/}/}
commands[0]="${commands[1]} $filename"
commands[1]=$tmp
printf -v new '%s`%s`' "$var" "$(IFS='|'; echo "${commands[*]}")"
echo "$new"
succ_1st=` sed '/localhost.localdomain/,/testdns.net/{//!d}' $path_tmp/named.stats.tmp|grep 'resulted in successful answer' | awk '{ print $1 }' | grep -m1 ''`