我想在Linux的find
命令中使用正则表达式来递归地跳入一个庞大的目录树,向我展示所有的.c,.cpp和.h文件,但省略了包含某些子字符串的匹配。最终,我想将输出发送到一个xargs
命令,以对所有匹配的文件执行特定处理。我可以通过grep管道输出find
以删除包含这些子字符串的匹配项,但该解决方案对于包含空格的文件名不起作用。所以我尝试使用find
的-print0选项,它终止每个文件名用一个nul字符而不是一个换行符(空白),并使用xargs -0
来期望nul-delimited输入,而不是空格分隔的输入,但我无法弄清楚如何通过管道grep过滤器成功地通过nul-delimited find
; grep -Z在这方面似乎没有帮助。如何从Linux的“find”命令的输出中排除匹配某些模式的目录?
所以我想我只是写一个更好的正则表达式为find
,并取消中间grep
过滤器...也许sed
将是一个替代?
在任何情况下,对目录的以下的小采样...
./barney/generated/bam bam.h
./barney/src/bam bam.cpp
./barney/deploy/bam bam.h
./barney/inc/bam bam.h
./fred/generated/dino.h
./fred/src/dino.cpp
./fred/deploy/dino.h
./fred/inc/dino.h
...我要输出到包括所有的.H,.C,和.cpp文件,但不是那些那些出现在'生成'和'部署'目录中的。
顺便说一句,你可以通过切割&粘贴在此整条生产线到您的bash shell创建用于测试的解决方案,这个问题整个测试目录(名为fredbarney):
mkdir fredbarney; cd fredbarney; mkdir fred; cd fred; mkdir inc; mkdir docs; mkdir generated; mkdir deploy; mkdir src; echo x > inc/dino.h; echo x > docs/info.docx; echo x > generated/dino.h; echo x > deploy/dino.h; echo x > src/dino.cpp; cd ..; mkdir barney; cd barney; mkdir inc; mkdir docs; mkdir generated; mkdir deploy; mkdir src; echo x > 'inc/bam bam.h'; echo x > 'docs/info info.docx'; echo x > 'generated/bam bam.h'; echo x > 'deploy/bam bam.h'; echo x > 'src/bam bam.cpp'; cd ..;
这个命令在所有的.H ,.C,和.cpp文件...
find . -regextype posix-egrep -regex ".+\.(c|cpp|h)$"
...但如果我管其通过xargs的输出时,“咣当咣当”文件分别获得视为两个独立的(不存在的)的文件名(注意这里我只是简单地使用ls
作为我交流的替身tually要与输出做):
$ find . -regextype posix-egrep -regex ".+\.(c|cpp|h)$" | xargs -n 1 ls
ls: ./barney/generated/bam: No such file or directory
ls: bam.h: No such file or directory
ls: ./barney/src/bam: No such file or directory
ls: bam.cpp: No such file or directory
ls: ./barney/deploy/bam: No such file or directory
ls: bam.h: No such file or directory
ls: ./barney/inc/bam: No such file or directory
ls: bam.h: No such file or directory
./fred/generated/dino.h
./fred/src/dino.cpp
./fred/deploy/dino.h
./fred/inc/dino.h
所以我可以提高,与-print0和-0参数传递给find
和xargs
:
$ find . -regextype posix-egrep -regex ".+\.(c|cpp|h)$" -print0 | xargs -0 -n 1 ls
./barney/generated/bam bam.h
./barney/src/bam bam.cpp
./barney/deploy/bam bam.h
./barney/inc/bam bam.h
./fred/generated/dino.h
./fred/src/dino.cpp
./fred/deploy/dino.h
./fred/inc/dino.h
...这是伟大的,但我不希望输出中的“生成”和“部署”目录。所以我试试这个:
$ find . -regextype posix-egrep -regex ".+\.(c|cpp|h)$" -print0 | grep -v generated | grep -v deploy | xargs -0 -n 1 ls
barney fred
......这显然不起作用。所以我尝试使用-Z选项和grep(不知道-Z选项到底是什么),那也不管用。所以,我想我会写一个更好的正则表达式find
,这是我能想出的最好:
find . -regextype posix-egrep -regex "(?!.*(generated|deploy).*$)(.+\.(c|cpp|h)$)" -print0 | xargs -0 -n 1 ls
...但庆典不喜欢这样(*:!未找到事件,无论这意味着),即使这不是一个问题,我的正则表达式似乎没有在我通常使用的正则表达式测试器网页上工作。
任何想法,我可以使这项工作?这是我想要的输出:
$ find . [----options here----] | [----maybe grep or sed----] | xargs -0 -n 1 ls
./barney/src/bam bam.cpp
./barney/inc/bam bam.h
./fred/src/dino.cpp
./fred/inc/dino.h
...我想避免脚本&临时文件,我想可能是我唯一的选择。
在此先感谢! 马克
'未找到事件'是因为'!'被解释为'bash'的历史扩展请求。单引号出现在其中的字符串,或给它一个额外的转义。我建议单引号! – Sorpigal 2012-07-12 16:27:47