以下脚本有效,但有什么用途declare $line?如果我删除它,它不起作用.
又什么的差异{} \;,并{} +在find命令?
awk '{print "old="$1" new="$2}' list.txt |\
while IFS= read line; do
declare $line
find /path -name '*.ext' -exec sed -i "s/\b$old\b/$new/" {} +
done
Run Code Online (Sandbox Code Playgroud)
该declare是设置变量:您的awk命令发出形式的内容old=foo new=bar.运行declare old=foo new=bar设置这两个变量.
也就是说,这是一种错误和草率的方式.相反,用于read直接从输入文件中读取所需的字段并分配给变量(在BashFAQ#1中有更多内容):
while read -u 3 -r old new _; do
find /path -name '*.ext' -exec sed -i "s/\b$old\b/$new/" {} +
done 3<list.txt
Run Code Online (Sandbox Code Playgroud)
为了使这更安全一点,人们也可以逃避文字内容而不被视为正则表达式:
requote() { sed 's/[^^]/[&]/g; s/\^/\\^/g' <<< "$1"; };
substquote() { sed 's/[&/\]/\\&/g' <<< "$1"; }
while read -u 3 -r old new _; do
find /path -name '*.ext' -exec \
sed -i "s/\b$(requote "$old")\b/$(substquote "$new")/" {} +
done 3<list.txt
Run Code Online (Sandbox Code Playgroud)
请注意,我没有改变使用\b,这是许多实现sed不支持的扩展.有关进行文字字符串替换的替代方法,请参阅BashFAQ#21.
为了完整性(虽然这个不相关的主题确实应该作为一个单独的问题提出 - 并且在这种情况下,可能已经被关闭为重复,因为之前已经被要求和回答过),请允许从find手册页中引用:
Run Code Online (Sandbox Code Playgroud)-exec command {} + This variant of the -exec action runs the specified command on the selected files, but the command line is built by appending each selected file name at the end; the total number of invoca? tions of the command will be much less than the number of matched files. The command line is built in much the same way that xargs builds its command lines. Only one instance of `{}' is allowed within the command. The command is executed in the starting directory.