如何搜索和替换与多个文件的替换列表匹配的字符串

Que*_*low 5 sed find search replace

我有一个文件,例如map.txt,包含搜索字符串列表和相应的替换:

search -> replacement
bigBone -> bb
fishMarket -> fm
dogCollar -> dc
...
Run Code Online (Sandbox Code Playgroud)

我需要在文件夹中递归地搜索和替换与上述所有文件匹配的所有字符串,但符号链接除外。我知道如何一次做一个这样的:

$ find /some/folder -type f -exec sed -i 's/old_text/new_text/g' {} \;
Run Code Online (Sandbox Code Playgroud)

如何使用上述映射大规模执行此操作?我已经阅读了这个问题,但不太明白。

Peq*_*que 4

回答

如果您不关心速度(这是一项一次性任务),那么也许您可以尝试以下操作:

cat map.txt | while read line; do
neww=${line##* };
oldw=${line%% *};
find /some/folder -type f -exec sed -i "s/$oldw/$neww/g" {} \;
done
Run Code Online (Sandbox Code Playgroud)

我知道这不是最佳选择...:-P

PS:检查一个测试文件夹,看看它是否有效!

解释

基本上:

  1. Cat 文件map.txt。
  2. 阅读每一行并获取要替换的单词$oldw和替换内容$neww
  3. 对于每一对,执行您已经使用的 find 命令(请注意这次的双引号,以便允许变量替换)。

关于参数扩展

为了设置变量$oldw$neww我们必须获取每行的第一个和最后一个单词。为此,我们使用参数扩展(纯 Bash 实现),尽管我们可以使用其他方法来获取字符串的第一个和最后一个单词(即 或cutawk

  • ${line##* }:从变量 中line,删除最大前缀 (double #) 模式,其中模式是任何字符 ( *) 后跟一个空格 ( )。所以我们得到了最后一句话line
  • ${line%% *}:从变量 中line,删除最大后缀 (double %) 模式,其中模式是一个空格 ( ) 后跟任何字符 ( *)。这样我们就得到了第一个单词line

在本例中,单词之间用空格分隔,但我们可以使用任何分隔符。