grep 使用一个文件路径,而不是另一个

0 command-line grep debian

我有两个目录,每个目录都有几千个文件,我试图从文件中 grep 某些 IP。我的 grep 字符串是:

grep "IP" cdr/173/07/cdr_2018_07*
Run Code Online (Sandbox Code Playgroud)

此 grep 字符串返回“grep:参数列表太长”。但是,当我执行以下操作时:

grep "IP" cdr/173/06/cdr_2018_06*
Run Code Online (Sandbox Code Playgroud)

它返回我正在寻找的东西。

下面是每个这些的父目录的 ls -l 。似乎差异大约是 400KB,所以我不确定大小是否真的是这里的问题。我错过了什么吗?

jeblin@debian:~$ ls -l cdr/173
total 18500
REDACTED
drwxr-xr-x 2 jeblin jeblin 2781184 Jul  2 09:34 06
drwxr-xr-x 2 jeblin jeblin 2826240 Aug  1 07:33 07
Run Code Online (Sandbox Code Playgroud)

如果它有所不同,我编写了一个 Python 脚本来自动执行此过程(搜索多个 IP),它适用于 06,但不适用于 07,这就是我尝试首先进行手动 grep 搜索的原因。

Kus*_*nda 6

shell 无法调用grep太多文件,或者更确切地说,用于调用外部实用程序的命令行1的长度有限制,当 shell 尝试grep使用扩展的通配 cdr/173/07/cdr_2018_07*模式调用时,您会遇到它。

您可以做的是单独 grep 每个文件,使用

for pathname in cdr/173/07/cdr_2018_07*; do
    grep "IP" "$pathname" /dev/null
done
Run Code Online (Sandbox Code Playgroud)

其中额外的/dev/null将强制grep始终报告匹配文件的文件名,或者您可以使用find:

find cdr/173/07 -maxdepth 1 -type f -name 'cdr_2018_07*' \
    -exec grep "IP" /dev/null {} +
Run Code Online (Sandbox Code Playgroud)

这将是更有效,因为grep将与被称为多路径名匹配尽可能分批。

也可能是如果你第一次cd进入cdr/173/07并做

grep "IP" cdr_2018_07*
Run Code Online (Sandbox Code Playgroud)

它可能会起作用,因为由于不包含目录位,生成的文件名列表会更短,但是您可能非常接近 44.7k 文件的限制,并且应该认真考虑采用另一种方式来执行此操作,特别是如果您预计文件数量会围绕该数字波动。

有关的:


1限制是命令行上的组合长度和环境的长度(每个参数的长度和环境变量的名称和值的总和,也包括指向它们的指针),这是由execve()shell 用来执行外部命令的系统调用。诸如echo等的内置命令没有这个问题。