我有一个文件,例如map.txt
,包含搜索字符串和相应替换的列表:
search -> replacement
bigBone -> bb
fishMarket -> fm
dogCollar -> dc
...
我需要对文件夹中除符号链接之外的所有文件递归地执行搜索和替换与上述匹配的所有字符串。我知道如何一次做一个,如下所示:
$ find /some/folder -type f -exec sed -i 's/old_text/new_text/g' {} \;
如何使用上述映射大规模执行此操作?我读过了这个问题,但不太明白。
答案1
回答
如果您不关心速度(这是一项一次性任务),那么也许您可以尝试以下操作:
cat map.txt | while read line; do
neww=${line##* };
oldw=${line%% *};
find /some/folder -type f -exec sed -i "s/$oldw/$neww/g" {} \;
done
我知道这不是最佳选择...:-P
PS:检查一个测试文件夹,看看它是否有效!
解释
基本上:
- Cat 文件map.txt。
- 阅读每一行并获取要替换的单词
$oldw
和替换内容$neww
。 - 对于每一对,执行您已经使用的 find 命令(请注意这次的双引号,以便允许变量替换)。
关于参数扩展
为了设置变量$oldw
,$neww
我们必须获取每行的第一个和最后一个单词。为此,我们使用参数扩展(纯 Bash 实现),尽管我们可以使用其他方法来获取字符串的第一个和最后一个单词(即cut
或awk
)。
${line##* }
:从变量 中line
,删除最大前缀 (double#
) 模式,其中模式是任何字符 (*
) 后跟一个空格 ()。所以我们得到了最后一句话
line
。${line%% *}
:从变量 中line
,删除最大后缀 (double%
) 模式,其中模式是一个空格 () 后跟任何字符 (
*
)。这样我们就得到了第一个单词line
。
在本例中,单词之间用空格分隔,但我们可以使用任何分隔符。
答案2
有时我需要搜索和替换配置文件中的术语。
我写了一个 github 上可用的脚本sandr - 搜索和替换它允许创建/使用地图并在文件中执行替换。
使用示例:
$ cat file
Voyez ce jeu exquis wallon, de graphie en kit mais bref. Portez ce vieux whisky au juge blond qui fume sur son île intérieure, à côté de l'alcôve ovoïde, où les bûches se consument dans l'âtre, ce qui lui permet de penser à la cænogenèse de l'être dont il est question dans la cause ambiguë entendue à Moÿ, dans un capharnaüm qui, pense-t-il, diminue çà et là la qualité de son œuvre. Prouvez, beau j
$ cat map.txt
wallon => WALLON
se => SE
penser => PENSER
beau => BEAU
$ cat file | ./sandr -a map.txt
Voyez ce jeu exquis WALLON, de graphie en kit mais bref. Portez ce vieux whisky au juge blond qui fume sur son île intérieure, à côté de l'alcôve ovoïde, où les bûches SE consument dans l'âtre, ce qui lui permet de PENSER à la cænogenèSE de l'être dont il est question dans la cauSE ambiguë entendue à Moÿ, dans un capharnaüm qui, penSE-t-il, diminue çà et là la qualité de son œuvre. Prouvez, BEAU j