如何使用带有空格和单引号的递归目录和文件名进行快速文本替换?最好使用标准 UNIX 工具,或者使用众所周知的软件包。
使用find
对于许多文件来说非常慢,因为它为每个文件生成一个新进程,所以我正在寻找一种将目录遍历和字符串替换集成为一个操作的方法。
慢搜索:
find . -name '*.txt' -exec grep foo {} \;
快速搜索:
grep -lr --include=*.txt foo
慢换:
find . -name '*.txt' -exec perl -i -pe 's/foo/bar/' {} \;
快速更换:
# Your suggestion here
(这个相当快,但是是两次通过并且不处理空格。)
perl -p -i -e 's/foo/bar/g' `grep -lr --include=*.txt foo`
您只想使用:
形式为那些
cmd
只能接受一个参数的 s。情况并非如此grep
。与grep
:(或
-H
与 GNU 一起使用grep
)。更多关于递归 grep 与 find / -type f -exec grep {} \; 哪个更高效/更快?现在进行替换,同样的,
perl -pi
可以采用多个参数:现在这将重写文件,无论它们是否包含
foo
。相反,您可能想要(假设 GNUgrep
和xargs
/或兼容):或者:
所以只有包含的文件
foo
被重写。顺便说一句,
--include=*.txt
(--include
作为另一个 GNU 扩展)是一个 shell glob,所以应该被引用。例如,如果--include=foo.txt
在当前目录中有一个文件被调用,shell 会--include=*.txt
在调用grep
. 如果没有,对于许多 shell,您会收到关于 glob 无法匹配任何文件的错误。所以你想要
grep --include='*.txt'
当您的
find
表达式如此简单时,您可以使用您的 shell 来代替进行 globbing。您可能遇到的主要限制是处理的文件多于命令行。bash 中的一个示例:
您可以使用
find ... -exec
“+”终止符代替“;” 大批量运行文件而不是一次运行一个文件(前提是正在exec
编辑的命令支持一次调用中的多个文件):