我知道有很多类似的问题但是,我想由于搜索/替换变量的格式化,它们对我的情况不起作用。
我正在处理的整个脚本将读取一个文本文件(使用grep和awk的组合)来创建两个shell变量$ find和$ replace。 $ find是包含所有字符的单行字符串。 $ replace是一个包含各种字符的多行字符串。
示例:
echo "$find"
返回
type result input1 another_input random_input<10> / name
和
echo "$replace"
返回
.TAG name
result input1 random_input / name1
random_input<10> input1 another_input / name2
.NTAG
现在我只需用$ replace替换$ find。我尝试过sed和perl但它失败了。
尝试过(在许多其他事情中)
perl -e -i.bak "s/$find/$replace/g" text.file
perl -e -i.bak 's,"'$find'","'$replace'",g' text.file
perl -e -i.bak "s|$find|$replace|g" text.file
和
sed -i "s/$find/$replace/g" text.file
我的猜测是问题是由字符串中的某些字符被解释为特殊字符引起的。
感谢任何帮助!
答案 0 :(得分:2)
这适用于任何查找或替换值:
$ cat file
foo
type result input1 another_input random_input<10> / name
bar
$ awk -v find="$find" -v replace="$replace" 's=index($0,find){$0=substr($0,1,s-1) replace substr($0,s+length(find))}1' file
foo
.TAG name
result input1 random_input / name1
random_input<10> input1 another_input / name2
.NTAG
bar
如果find
总是一行,则可以简化,例如这可能是你所需要的:
$ awk -v find="$find" -v replace="$replace" '$0==find{$0=replace}1' file
foo
.TAG name
result input1 random_input / name1
random_input<10> input1 another_input / name2
.NTAG
bar
答案 1 :(得分:0)
将您的变量重组为
replace=".TAG name\nresult input1 random_input / name1\nrandom_input<10> input1 another_input / name2\n.NTAG"
或像这样重组
replace='.TAG name\
result input1 random_input / name1\
random_input<10> input1 another_input / name2\
.NTAG'
此外,您的分隔符与变量replace
字符发生冲突,因为变量中有/
您可以尝试使用#
作为分隔符或任何其他不在变量中的字符
sed "s#$find#$replace#g" text_file
答案 2 :(得分:0)
一种方式用sed,快速和脏,所以不像@Ed Morton的awk那样的防弹
find_sed="$( printf "%s" "${find}" | sed 's/[^0-9(){}]/\\&/g' )"
replace_sed="$( printf "%s" "${replace}" | sed "s/[&\\]/\\/g;s/\n/\\&/g' )"
sed "s/${find_sed}/${replace_sed}/g" YourFile
--posix
与GNU sed),如果不是posix,则根据您使用转义字符的特殊字符调整[^0-9(){}]
,以获取\+\n\d\