我有一个文件“changesDictionary.txt”,其中包含(可变数量的)键值字符串对。
例如
“textToSearchFor”=“theReplacementText”
(词典的格式不重要,根据需要更改。)
我需要迭代给定目录的内容,包括子目录。对于遇到的扩展名为“.txt”的每个文件,我们在changesDictionary.txt中搜索each键,用替换字符串值替换每个找到的实例。
即对多个文件进行搜索和替换,但使用搜索/替换术语列表而不是单个搜索/替换术语。
我怎样才能做到这一点? (我研究过单个搜索/替换示例,但不明白如何在一个文件中进行多个搜索。)
只要我可以从 Mac OS X 中的命令行运行它,实现(bash、perl 等)并不重要。感谢您的帮助。
我会将您的changesDictionary.txt 文件转换为 sed 脚本,使用... sed:
$ sed -e 's/^"\(.*\)" = "\(.*\)"$/s\/\1\/\2\/g/' \
changesDictionary.txt > changesDictionary.sed
注意,字典中正则表达式或 sed 表达式的任何特殊字符都将被 sed 错误地解释,因此你的字典要么只有最原始的搜索和替换,要么你需要维护包含有效表达式的 sed 文件。不幸的是,sed 中没有简单的方法来关闭正则表达式并仅使用字符串匹配或将您的搜索和替换引用为“文字”。
对于生成的 sed 脚本,使用 find 和 xargs ——而不是 find -exec ——通过一次处理多个文件来尽快使用 sed 脚本转换文件。
$ find somedir -type f -print0 \
| xargs -0 sed -i -f changesDictionary.sed
注意,sed 的
-i
选项“就地”编辑文件,因此请务必进行备份以确保安全,或使用 -i~
创建波形符备份。
最后一点,使用搜索和替换可能会产生意想不到的后果。您的搜索是否是其他搜索的子字符串?这是一个例子。
$ cat changesDictionary.txt
"fix" = "broken"
"fixThat" = "Fixed"
$ sed -e 's/^"\(.*\)" = "\(.*\)"$/s\/\1\/\2\/g/' changesDictionary.txt \
| tee changesDictionary.sed
s/fix/broken/g
s/fixThat/Fixed/g
$ mkdir subdir
$ echo fixThat > subdir/target.txt
$ find subdir -type f -name '*.txt' -print0 \
| xargs -0 sed -i -f changesDictionary.sed
$ cat subdir/target.txt
brokenThat
“fixThat”应该变成“Fixed”还是“brokenThat”?顺序对于 sed 脚本很重要。类似地,搜索和替换可以多次搜索和替换 - 将“a”更改为“b”,稍后可能会被另一个搜索和替换从“b”更改为“c”。
也许您已经考虑过这两个问题,但我之所以提到,是因为我已经尝试过您之前所做的事情,但没有想到。我不知道有什么可以简单地“做正确的事情”来同时进行多个搜索和替换。因此,您需要对其进行编程,以便自己做正确的事情。
复制changesDictionary.txt文件
sed -e 's/a/b/g' $1
(如果您只需要执行一次并且它不是太大,您可以编写一个脚本来执行此操作,也可以手动执行此操作)。
ls *.txt | xargs scriptFromStep2.sh
找到。 -name '*.txt' -exec scriptFromStep2.sh {} \;
(但是,如果可以的话,就用perl吧,会简单很多)
ls -1 /script/arq*.sh
做 echo -e“ARQUIVO ${i}” sed -i 's|/$file_path1|/file_path2|g' ${i} 完成