我正在尝试使用sed命令查找和替换特定的文本内容,并通过Shell脚本运行它。
下面是我正在使用的示例脚本:
fp=/asd/filename.txt
fd="sed -i -E 's ($2).* $2:$3 g' ${fp}"
eval $fd
并通过传递参数来执行该操作:
./test.sh update asd asdfgh
但是,如果参数字符串包含$
,则会破坏命令,并替换为错误的值,例如
./test.sh update asd $apr1$HnIF6bOt$9m3NzAwr.aG1Yp.t.bpIS1.
如何确保由于$
而不会扩展变量内部的值?
sh文件test.sh
set -xv
fp="/asd/filename.txt"
sed -iE "s/(${2//'$'/'\$'}).*/${2//'$'/'\$'}:${3//'$'/'\$'}/g" "$fp"
文本文件filename.txt
hello:world
输出
1) ./test.sh更新世界您好
sed -iE "s/(${2//'$'/'\$'}).*/${2//'$'/'\$'}:${3//'$'/'\$'}/g" "$fp"
++ sed -iE 's/(hello).*/hello:WORLD/g' /asd/filename.txt
2) ./test.sh更新你好'$ apr1 $ hosgaxyv $ D0KXp5dCyZ2BUYCS9BmHu1'
sed -iE "s/(${2//'$'/'\$'}).*/${2//'$'/'\$'}:${3//'$'/'\$'}/g" "$fp"
++ sed -iE 's/(hello).*/hello:'\''$'\''apr1'\''$'\''hosgaxyv'\''$'\''D0KXp5dCyZ2BUYCS9BmHu1/g' /asd/filename.txt
在两种情况下,它都不能替换内容
答案 0 :(得分:2)
您根本不需要eval
:
fp=/asd/filename.txt
sed -i -E "s/(${2//'$'/'\$'}).*/\1:${3//'$'/'\$'}/g" "$fp"
s
替换为/
(在示例中并不重要)。\1
来引用第一个捕获组,而不是在替换中重复该变量。${2//'$'/'\$'}
而不是$2
(对于$3
也是如此)。这会将每个$
符号转义为\$
;这是必需的,因为有双引号,或者$
在sed看到它们之前被外壳吃掉了。调用脚本时,必须对输入中的所有$
进行转义,否则shell会尝试将它们扩展为变量名:
./test.sh update asd '$apr1$HnIF6bOt$9m3NzAwr.aG1Yp.t.bpIS1.'
答案 1 :(得分:0)
将文件名中的命令行参数放在单引号中
./test.sh update 'asd' '$apr1$HnIF6bOt$9m3NzAwr.aG1Yp.t.bpIS1'
答案 2 :(得分:0)
如果有空格和特殊的shell字符,必须用引号保护所有脚本参数,如果是美元$
和-Ei
而不是-iE,则最好将其转义以进行测试,如果确定的话可以稍后再添加
我承认我不会对您的正则表达式有所了解,所以让我们进入解决方案的要旨,无需评估;
fp=/asd/filename.txt
sed -Ei "s/($2).*/$2:$3/g" $fp
./test.sh update asd '\$apr1\$HnIF6bOt\$9m3NzAwr.aG1Yp.t.bpIS1.'