【问题标题】:Global substitution shell script not working全局替换 shell 脚本不起作用
【发布时间】:2012-08-04 06:52:42
【问题描述】:

我有一个类似的 shell 脚本:

for fl in /home/dr/*.txt; do
mv $fl $fl.old
sed 's#$1#$2#g' $fl.old > $fl
rm -f $fl.old
done

我像./script.sh find replace 一样运行它,但什么也没发生,也没有输出。为什么是这样?

【问题讨论】:

  • 内单引号' $1$2 可能不是你的意思。

标签: shell ubuntu sed


【解决方案1】:

问题是您使用的是单引号而不是双引号。使用单引号,sed 按字面意思解释字符串(即,它将搜索字符串 $1,而不是第一个参数)。

以下是您尝试执行的功能的版本。请注意,我已将临时文件使用替换为 sed 的“就地”编辑。

for fl in /home/dr/*.txt
do
  sed -i "s#$1#$2#g" $fl
done

但是,你可以把所有东西都写成一行

sed -i "s#$1#$2#g" /home/dr/*.txt

【讨论】:

  • 感谢您的精彩回答。如果 $1 包含一个 '/' 这会导致问题吗?这就是为什么我用# 符号代替。并且是'。故意从 txt 中省略?
  • 是的,这会导致问题,正因为如此,# 是一个更好的选择。对此感到抱歉。我只是习惯性地使用斜线。
  • 不,由于我的草率,省略了.。很好,我再次道歉。
  • 感谢您的建议 +1,但由于某种原因,单线没有编辑任何文件。多线一号我没测试过
  • 它不起作用的原因是因为单引号内的所有内容都是按字面意思获取的(即它将搜索字符串$1,而不是第二个参数)。我的答案现在已经确定了。它应该可以解决问题。
【解决方案2】:

这可能对你有用(GNU sed):

sed -i "s#$1#$2#g" /home/dr*.txt

您遇到的问题是 sed 命令周围的单引号不允许插值。

【讨论】:

  • 您似乎接受了错误的答案。 接受的答案被破坏了。
  • 这样更好,@David。还有一件事:不需要反引号。如果您删除那些我也会赞成您的答案。原因:他们分散了原始问题的注意力。
  • @Henk,我刚刚测试过......看来你是对的!感谢您的更正,这改变了我的很多 bash 脚本。现在编辑我的答案。
  • @Henk,它已被更改。您介意指出未来的错误作为对答案的回应吗?如果我没有再次检查这个帖子,我将永远没有机会被纠正。
  • 您可以将dodone 对齐吗?或者,删除do 并在前一行添加一个`;do`。两者都是很好的风格。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-04-29
  • 1970-01-01
  • 1970-01-01
  • 2011-12-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多