查找并替换文件中的文本。查找单词始终相同,并且替换字符串会一直变化
我正在尝试一个简单的sed脚本(test.sh)来实现这个,它使用一个参数(一个带有特殊字符的长字符串):
sed -i "s/#####REPLACE#####/$1/g" file.txt
结果应该使用我传递给脚本#####REPLACE#####
的参数替换test.sh
。
参数一直在变化,并且包含许多特殊字符(如下所示):
"abc"/def:-/ghi$jklmno-pqrblah..blah..very..long..string
我正在尝试的命令是:
./test.sh "abc"/def:-/ghi$jklmno-pqrblah..blah..very..long..string
它给出了以下信息:
sed: -e expression #1, char 25: unknown option to `s'
我有很多文件(例如file1.txt
,file2.txt
,file3.txt
),相同的公共文本#####REPLACE#####
将被相同的参数"abc"/def:-/ghi$jklmno-pqrblah..blah..very..long..string
替换。
有什么建议吗?
答案 0 :(得分:2)
一种选择是使用awk:
awk -v replace="$1" '{ gsub(/#####REPLACE#####/, replace); print }' file
这将awk变量replace
设置为等于传递给函数$1
的第一个参数,然后对file
的每一行执行全局替换。
要覆盖文件"就地",只需使用awk ... file > tmp && mv tmp file
。
这种方法优于使用sed的优点是替换字符串*中出现的字符并不重要;它们永远不会导致语法错误。
*正如评论中指出的那样,有一个角色会破坏:&
由于您只对执行字符串替换(而非正则表达式替换)感兴趣,另一种选择是使用以下内容:
awk -v replace="$1" '{
out = ""
while(match($0, /#####REPLACE#####/)) {
out = out substr($0, 0, RSTART - 1) replace
$0 = substr($0, RSTART + RLENGTH)
}
print out $0}' file
使用输入记录out
和变量$0
的组合构建替换字符串replace
。
答案 1 :(得分:0)
问题是你在sed中使用/
作为正则表达式分隔符,同样的字符也是替换字符串的一部分。在sed
中使用备用正则表达式分隔符:
sed -i "s~#####REPLACE#####~$1~g" file.txt
这是假设~
(代字号)不在替换文本中。如果是这种情况,那么您甚至可以使用控制字符,例如^A
ctrl V A (压在一起)作为正则表达式分隔符。
sed -i "s^A#####REPLACE#####^A$1^Ag" file.txt
PS:如果您想在&
中将&
作为文字$1
传递,请将其作为\&