Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux 如何并行grep_Linux_Grep - Fatal编程技术网

Linux 如何并行grep

Linux 如何并行grep,linux,grep,Linux,Grep,我通常使用grep-rIn模式\u str big\u source\u code\u dir来查找一些东西。但是grep不是并行的,如何使它并行?我的系统有4个核心,如果grep可以使用所有核心,那么速度会更快。如果您使用HDD存储您正在搜索的目录,则速度不会提高。硬盘几乎都是单线程访问单元 但是如果你真的想做并行grep,那么就给你两个提示,告诉你如何使用find和xargs。例如 find . -type f -print0 | xargs -0 -P 4 -n 40 grep -i fo

我通常使用
grep-rIn模式\u str big\u source\u code\u dir
来查找一些东西。但是
grep
不是并行的,如何使它并行?我的系统有4个核心,如果
grep
可以使用所有核心,那么速度会更快。

如果您使用HDD存储您正在搜索的目录,则速度不会提高。硬盘几乎都是单线程访问单元

但是如果你真的想做并行grep,那么就给你两个提示,告诉你如何使用
find
xargs
。例如

find . -type f -print0 | xargs -0 -P 4 -n 40 grep -i foobar

GNU
parallel
命令在这方面非常有用

sudo apt-get install parallel # if not available on debian based systems
然后,
paralell
手册页提供了一个示例:

EXAMPLE: Parallel grep
       grep -r greps recursively through directories. 
       On multicore CPUs GNU parallel can often speed this up.

       find . -type f | parallel -k -j150% -n 1000 -m grep -H -n STRING {}

       This will run 1.5 job per core, and give 1000 arguments to grep.
在您的情况下,可能是:

find big_source_code_dir -type f | parallel -k -j150% -n 1000 -m grep -H -n pattern_str {}
最后,GNU parallel手册页还提供了一个部分,描述了
xargs
parallel
命令之间的差异,这将有助于理解为什么在您的情况下,parallel看起来更好

DIFFERENCES BETWEEN xargs AND GNU Parallel
       xargs offer some of the same possibilities as GNU parallel.

       xargs deals badly with special characters (such as space, ' and "). To see the problem try this:

         touch important_file
         touch 'not important_file'
         ls not* | xargs rm
         mkdir -p "My brother's 12\" records"
         ls | xargs rmdir

       You can specify -0 or -d "\n", but many input generators are not optimized for using NUL as separator but are optimized for newline as separator. E.g head, tail, awk, ls, echo, sed, tar -v, perl (-0 and \0 instead of \n),
       locate (requires using -0), find (requires using -print0), grep (requires user to use -z or -Z), sort (requires using -z).

       So GNU parallel's newline separation can be emulated with:

       cat | xargs -d "\n" -n1 command

       xargs can run a given number of jobs in parallel, but has no support for running number-of-cpu-cores jobs in parallel.

       xargs has no support for grouping the output, therefore output may run together, e.g. the first half of a line is from one process and the last half of the line is from another process. The example Parallel grep cannot be
       done reliably with xargs because of this.
       ...

请注意,您需要对并行grep搜索词中的特殊字符进行转义,例如:

parallel--pipe--block 10M--ungroup LC\u ALL=C grep-F'PostTypeId=\'1\'<~/Downloads/Posts.xml>questions.xml

使用独立grep,
grep-F'PostTypeId=“1”
将在不转义双引号的情况下工作。我花了一段时间才弄明白


还要注意使用
LC_ALL=C
-F
标志(如果您只是在搜索完整字符串)来获得额外的速度提升。

这里有三种方法,但您无法获得其中两种的行号

(1) 在多个文件上并行运行grep,在本例中是一个目录及其子目录中的所有文件。添加
/dev/null
以强制grep将文件名前置到匹配行,因为您需要知道匹配的文件。调整机器的进程数
-P

find-类型f | xargs-n1-p4 grep-n/dev/null
(2) 在多个文件上串行运行grep,但并行处理10M块。调整计算机和文件的块大小。这里有两种方法

#用于循环
查找中的文件名-f型`
做
parallel--pipepart--block 10M-a$filename-k“grep | awk-v OFS=:“{print\“$filename\”,\$0}”
完成
#使用xargs
找到-键入f | xargs-I filename parallel--pipepart--block 10M-a filename-k“grep | awk-v OFS=:“{print\'filename\',\$0}”
(3) 合并(1)和(2):在多个文件上并行运行grep,并在块中并行处理其内容。调整机器的块大小和xargs并行度

find-键入f | xargs-n1-p4-I filename parallel--pipepart--block 10M-a filename-k“grep | awk-v OFS=:“{print\'filename\',\$0}”
注意(3)可能不是资源的最佳使用


我有一个简单的例子,但这是基本的想法。

我从源网站复制了错误的例子,对不起。我会修正答案。请注意,使用
xargs
可能会得到混合输出。要实际了解这一点,请参见:在同一目录树上重复执行grep时,并行grep的好处是显而易见的,例如,对于同一源代码中的不同关键字。文件内容将缓存在RAM中(当然,这取决于您有多少RAM和源代码)。我还没有试过这个软件,但它可能很快。我不同意。进行grepping时,限制因素是IO吞吐量,而不是CPU时间。在这个问题上抛出更多内核并不会使磁盘旋转更快。我不同意你的观点:#time grep-E“无效用户(\S+)来自([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+])端口([0-9]+)“/var/log/auth.log在我的i7上显示10秒,然后测试驱动器的速度:#dd if=/var/log/auth.log of=/dev/null bs=1M,以130MB/s的速度读取600MB数据需要4秒,但上面的grep需要3秒以上的时间,接近40MB/s。因此,这里正则表达式的处理时间是并行运行中最扩展的:parallel--pipe--block 16M grep-E“来自([0-9]+\[0-9]+\[0-9]+\[0-9]+\[0-9]+]端口([0-9]+])的无效用户(\S+)”这似乎是最好的答案,为什么不是更高?因为它不起作用。。幸运的是,我能够使用
comm
来解决我的特殊问题,在相同的情况下,这比
grep
要快得多。并行grep对于具有高延迟的网络装载非常方便。