Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bash 如何搜索和替换文件中包含空格并由变量表示的多行文本?_Bash_Shell_Perl_Sed - Fatal编程技术网

Bash 如何搜索和替换文件中包含空格并由变量表示的多行文本?

Bash 如何搜索和替换文件中包含空格并由变量表示的多行文本?,bash,shell,perl,sed,Bash,Shell,Perl,Sed,我有一个文件input.txt,其中包含以下文本: abc def ghi jkl mno pqr stu vwx 我可以使用以下命令替换文件中的两行: perl -i -p0e 's/ghi jkl\nmno pqr/zyx wvu\ntsr qpo/s' input.txt 但是,我需要在变量中搜索和替换字符串: search_s="ghi jkl\nmno pqr" replace_s="zyx wvu\ntsr qpo" perl -i -p0e 's/'$search_s'/'$

我有一个文件input.txt,其中包含以下文本:

abc def
ghi jkl
mno pqr
stu vwx
我可以使用以下命令替换文件中的两行:

perl -i -p0e 's/ghi jkl\nmno pqr/zyx wvu\ntsr qpo/s' input.txt
但是,我需要在变量中搜索和替换字符串:

search_s="ghi jkl\nmno pqr"
replace_s="zyx wvu\ntsr qpo"
perl -i -p0e 's/'$search_s'/'$replace_s'/s' input.txt
但是现在这个命令不适用于变量:

search_s="ghi jkl\nmno pqr"
replace_s="zyx wvu\ntsr qpo"
perl -i -p0e 's/'$search_s'/'$replace_s'/s' input.txt
我得到的错误替换模式未终止于-e第1行。。问题似乎出在$search\s变量中的空格附近。我尝试了各种方法对空间进行编码,但没有成功

注意:我使用的是perl命令,因为它可以很好地处理文件中包含\n的搜索和替换。我试过sed,但不是很好

是否有人可以帮助我对空间进行编码,使其在变量或另一个命令中工作,该命令将对文件执行搜索和替换,同时保留\n

谢谢,
Rob

这里的混乱之处在于shell引用。当你写作时

perl -i -p0e 's/'$search_s'/'$replace_s'/s' input.txt
shell解析它并使用以下参数调用perl:-i-p03 s/ghi jkl\nmno pqr/zyx wvu。。。 这不是你想要的。之所以会发生这种情况,是因为shell在扩展变量后执行单词拆分。要防止出现这种情况,您需要引用以下参数:

perl -i -p0e "s/$search_s/$replace_s/s" input.txt

当您想在多行上进行匹配时,awk很有趣

使用awk,您可以用不同的方式处理此问题。 我的解决方案是将每一行存储在一个数组中,并在看到时更改存储的数据, 我有两条匹配的线

awk -v line1="ghi jkl" -v line2="mno pqr" '
   {a[NR]=$0}
   $0==line1 {m1=1; next}
   $0==line2 {a[NR-1]="zyx wvu"; a[NR]="tsr qpo"; m1=0}
   END {for (i=1;i<=NR;i++) print a[i]}
   ' input.txt

另一种没有数组的解决方案是记住第一行,当第二行没有完成匹配时打印它。使用匹配项,打印替换字符串,不要忘记在不属于匹配项的情况下打印最后一行的END语句。

分词就是分割参数。尝试perl-i-p0e s/$search\u s/$replace\u s/s这可能意味着您还需要双重转义换行符-\\n。