首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >递归目录中的快速字符串替换

递归目录中的快速字符串替换
EN

Unix & Linux用户
提问于 2018-03-29 18:28:02
回答 2查看 1.7K关注 0票数 0

如何用递归目录和带有空格和单引号的文件名替换快速文本?最好使用标准的UNIX工具,或者是众所周知的软件包.

对于许多文件来说,使用find非常慢,因为它会为每个文件生成一个新的进程,因此我正在寻找一种将目录遍历和字符串替换集成为一个操作的方法。

缓慢搜索:

代码语言:javascript
复制
find . -name '*.txt'  -exec grep foo {} \;

快速搜索:

代码语言:javascript
复制
grep -lr --include=*.txt foo

缓慢替换:

代码语言:javascript
复制
find . -name '*.txt' -exec perl -i -pe 's/foo/bar/' {} \;

快速替换:

代码语言:javascript
复制
# Your suggestion here

(这个速度相当快,但是两次传球,不处理空间。)

代码语言:javascript
复制
perl -p -i -e 's/foo/bar/g' `grep -lr --include=*.txt foo`
EN

回答 2

Unix & Linux用户

回答已采纳

发布于 2018-03-29 19:55:58

您只需要使用:

代码语言:javascript
复制
 find . -name '*.txt'  -exec cmd {} \;

对于那些只能拿一个论点的cmds来说。这不是grep的情况。使用grep

代码语言:javascript
复制
 find . -name '*.txt'  -exec grep foo /dev/null {} +

(或将-H与GNU grep一起使用)。在-type f -exec grep {};哪个更有效/更快?会有更多的相关信息。

对于替换,这是相同的,perl -pi可以使用多个参数:

代码语言:javascript
复制
 find . -name '*.txt' -type f -exec perl -pi -e s/foo/bar/g {} +

现在,不管文件是否包含foo,都将重写它们。相反,您可能希望(假设GNU grepxargs或兼容):

代码语言:javascript
复制
 find . -name '*.txt' -type f -exec grep -l --null foo {} + |
   xargs -r0 perl -pi -e s/foo/bar/g

或者:

代码语言:javascript
复制
 grep -lr --null --include='*.txt' foo . |
   xargs -r0 perl -pi -e s/foo/bar/g

因此,只有包含foo的文件才被重写。

顺便说一下,--include=*.txt (--include是另一个GNU扩展)是一个shell glob,因此应该引用。例如,如果当前目录中有一个名为--include=foo.txt的文件,则shell将在调用grep之前将--include=*.txt展开到该文件。如果不是,使用许多shell,您将得到一个关于glob未能匹配任何文件的错误。

所以你会想要grep --include='*.txt'

票数 5
EN

Unix & Linux用户

发布于 2018-03-29 19:55:49

可以将find ... -exec与"+“终止符一起使用,而不是";”以大批而不是一次运行文件(前提是execed命令在一次调用中支持多个文件):

代码语言:javascript
复制
find . -name '*.txt' -exec grep foo {} +
find . -name '*.txt' -exec perl -i -pe 's/foo/bar/' {} +
票数 0
EN
页面原文内容由Unix & Linux提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://unix.stackexchange.com/questions/434361

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档