我正在尝试grep
在当前目录中的40k文件,我收到此错误.
for i in $(cat A01/genes.txt); do grep $i *.kaks; done > A01/A01.result.txt
-bash: /usr/bin/grep: Argument list too long
Run Code Online (Sandbox Code Playgroud)
一般如何grep
成千上万的文件?
谢谢Upendra
Dav*_* W. 29
这让大卫伤心......
到目前为止,每个人都错了(除了anubhava).
Shell脚本与任何其他编程语言都不同,因为对行的大部分解释来自shell在实际执行命令之前插入它们的强大功能.
我们来看一些简单的事情:
$ set -x
$ ls
+ ls
bar.txt foo.txt fubar.log
$ echo The text files are *.txt
echo The text files are *.txt
> echo The text files are bar.txt foo.txt
The text files are bar.txt foo.txt
$ set +x
$
Run Code Online (Sandbox Code Playgroud)
将set -x
让你看到的外壳实际上是如何插值的水珠,然后通过该回命令输入.>
指向实际执行的行的点.
你可以看到该echo
命令没有解释*
.相反,shell抓取*
并用匹配文件的名称替换它.然后,只有这样echo
命令才能实际执行命令.
如果你有40K以上的文件,你就grep *
可以将它扩展*
到那些40,000多个文件的名称,grep
甚至有机会执行,这就是错误消息/ usr/bin/grep:参数列表太长的地方了来自(哪里.
幸运的是,Unix有办法解决这个难题:
$ find . -name "*.kaks" -type f -maxdepth 1 | xargs grep -f A01/genes.txt
Run Code Online (Sandbox Code Playgroud)
该find . -name "*.kaks" -type f -maxdepth 1
会发现所有的*.kaks
文件,并且-depth 1
将只包括在当前目录下的文件.在-type f
确保你只拿起文件,而不是一个目录.
该find
命令通过管道将文件转换成的名称xargs
和xargs
将附加文件的名称grep -f A01/genes.txt
命令.但是,xargs
有一个技巧.它知道命令行缓冲区的长度,并grep
在命令行缓冲区已满时执行,然后将另一系列文件传递给grep
.这样,grep
执行可能会执行三次或十次(取决于命令行缓冲区的大小),并且我们使用了所有文件.
不幸的是,xargs
使用空格作为文件名的分隔符.如果您的文件包含空格或制表符,则会遇到问题xargs
.幸运的是,还有另一种解决方法:
$ find . -name "*.kaks" -type f -maxdepth 1 -print0 | xargs -0 grep -f A01/genes.txt
Run Code Online (Sandbox Code Playgroud)
这-print0
将导致find
打印出不是由换行符分隔的文件的名称,而是打印出由NUL字符分隔的文件的名称.在-0
为参数xargs
告诉xargs
该文件分隔符不是空白,但NULL字符.因此,解决了这个问题.
你也可以这样做:
$ find . -name "*.kaks" -type f -maxdepth 1 -exec grep -f A01/genes.txt {} \;
Run Code Online (Sandbox Code Playgroud)
这将为grep
找到的每个文件执行for而不是为命令行上的所有文件xargs
运行grep
.这样做的好处是它完全避免了外壳干扰.但是,效率可能会降低,也可能不会降低.
有趣的是试验并看哪哪个更有效.你可以用time
来看:
$ time find . -name "*.kaks" -type f -maxdepth 1 -exec grep -f A01/genes.txt {} \;
Run Code Online (Sandbox Code Playgroud)
这将执行命令然后告诉你它花了多长时间.尝试使用-exec
和,xargs
并看看哪个更快.让我们知道你发现了什么.
您可以结合find
使用grep
这样的:
find . -maxdepth 1 -name '*.kaks' -exec grep -H -f A01/genes.txt '{}' \; > A01/A01.result.txt
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
15303 次 |
最近记录: |