7 bash shell sed pipe find-util
我有这个find命令:
find . -type f -not -path '**/.git/**' -not -path '**/node_modules/**' | xargs sed -i '' s/typescript-library-skeleton/xxx/g;
Run Code Online (Sandbox Code Playgroud)
由于某种原因,它给了我这些警告/错误:
find: ./.git/objects/3c: No such file or directory
find: ./.git/objects/3f: No such file or directory
find: ./.git/objects/41: No such file or directory
Run Code Online (Sandbox Code Playgroud)
我甚至尝试过使用:
-not -path '**/.git/objects/**'
Run Code Online (Sandbox Code Playgroud)
得到了同样的事情.有人知道为什么查找在.git
目录中搜索?看起来很奇怪.
为什么在.git目录中搜索?
GNU find
很聪明,并支持对一个简单实现的几个优化:
-size +512b -name '*.txt'
并首先检查名称,因为查询大小将需要第二个系统调用.-type d
或用于递归.(-B -or -C) -and -A
以便如果检查成本相同且没有副作用,-A
将首先评估,希望在1次测试后拒绝该文件而不是2.然而,它还不够聪明,意识到这-not -path '*/.git/*'
意味着如果你找到一个目录,.git
那么你甚至不需要递归到它,因为里面的所有文件都无法匹配.
相反,它尽职地递归,找到每个文件并将其与模式匹配,就好像它是一个黑盒子一样.
要明确告诉它完全跳过目录,您可以改为使用-prune
.请参见如何在find中排除目录.命令
更高效和更正确的方法是避免默认-print
操作,更改-not -path ...
为-prune
,并确保xargs
仅用于NUL分隔的输入:
find . -name .git -prune -o \
-name node_modules -prune -o \
-type f -print0 | xargs -0 sed -i '' s/typescript-library-skeleton/xxx/g '{}' +
Run Code Online (Sandbox Code Playgroud)
请注意以下几点:
-prune
用来告诉find
甚至没有递减不需要的目录,而不是-not -path ...
告诉它在找到它们之后丢弃这些目录中的名字.-prune
小号之前的-type f
,所以我们能够匹配目录修剪.-print
.这很重要,因为默认情况下-print
有效地有一组括号:如果给出明确的操作,则find ...
表现得像find '(' ... ')' -print
,不喜欢find ... -print
,不行.xargs
仅使用-0
支持NUL分隔输入的参数,以及侧面的-print0
操作find
来生成NUL分隔的名称列表.NUL是唯一不能出现在任意文件路径中的字符(是的,可以存在换行符) - 因此是唯一可以安全地用于分隔路径的字符.(如果不保证-0
扩展名xargs
和-print0
扩展名find
可用,请-exec sed -i '' ... {} +
改用). 归档时间: |
|
查看次数: |
75 次 |
最近记录: |