grep funciona com um caminho de arquivo, não outro

0

Eu tenho dois diretórios que possuem dois milhares de arquivos cada, e estou tentando obter determinados IPs dos arquivos. Minha string do grep é:

grep "IP" cdr/173/07/cdr_2018_07*

Esta string do grep retorna "grep: Argument list too long". No entanto, quando faço o seguinte:

grep "IP" cdr/173/06/cdr_2018_06*

retorna o que estou procurando.

Abaixo está o ls -l para o diretório pai de cada um deles. Parece que a diferença é de cerca de 400KB, então não tenho certeza se o tamanho é realmente o problema aqui. Estou faltando alguma coisa?

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

Se isso faz diferença, eu escrevi um script Python que automatiza esse processo (procurando por vários IPs), e funciona para 06, mas não 07 também, e é por isso que tentei fazer a pesquisa grep manual primeiro.

    
por Josh Eblin 01.08.2018 / 17:29

3 respostas

6

O shell não é capaz de chamar grep com muitos arquivos, ou melhor, o comprimento da linha de comando 1 para chamar um utilitário externo tem um limite, e você está acertando quando o shell tenta chamar grep com o padrão expandido cdr/173/07/cdr_2018_07* globbing.

O que você pode fazer é para grep cada arquivo individualmente, com

for pathname in cdr/173/07/cdr_2018_07*; do
    grep "IP" "$pathname" /dev/null
done

em que o /dev/null extra forçará grep a sempre informar o nome do arquivo do arquivo correspondente ou você pode usar find :

find cdr/173/07 -maxdepth 1 -type f -name 'cdr_2018_07*' \
    -exec grep "IP" /dev/null {} +

que será mais eficiente, pois grep será chamado com tantos nomes de caminhos correspondentes quanto possível em lotes.

Também pode ser que, se você primeiro cd em cdr/173/07 e faça

grep "IP" cdr_2018_07*

pode funcionar uma vez que a lista gerada de nomes de arquivos seria mais curta devido a não conter os bits do diretório, mas você provavelmente está muito próximo do limite com 44.7k arquivos e deve considerar seriamente mudar para Outra maneira de fazer isso, especialmente se você está esperando o número de arquivos para flutuar em torno desse número.

Relacionados:

1 O limite está no comprimento combinado na linha de comando e o comprimento do ambiente (a soma do comprimento de cada argumento e variável de ambiente) nome e valor, também considerando os ponteiros para eles), e é um limite imposto pela chamada de sistema execve() que é usada pelo shell para executar comandos externos. Comandos incorporados, como echo etc., não têm esse problema.

    
por 01.08.2018 / 17:42
1

O problema é o limite máximo de bytes permitidos no comando shell.

* é expandido para a lista total de todos os arquivos no diretório, portanto, o que importa não é o tamanho do arquivo, mas o tamanho dos arquivos e a quantidade de arquivos.

Você pode obter o limite da sua máquina em bytes executando $ getconf ARG_MAX . Por favor note que este limite é imposto pelo OS / Kernel e não pelo próprio shell.

Uma maneira de contornar isso é usar o find:

$ find cdr/173/07/ -iname "cdr_2018_07*" -type f -exec grep "IP" {} \;

    
por 01.08.2018 / 17:42
0

estou respondendo a questão com base nos pontos abaixo: Existem dois diretórios: 1) cdr / 173/07 2) cdr / 173/06

Pode haver muitos arquivos nesses dois diretórios dos quais preciso pesquisar

a) Abaixo está a primeira solução

grep -r "IP" cdr / 173/07 -e "IP" cdr / 173/06

b) Mas se houver muitos outros diretórios que você deseja pesquisar, você pode usar

grep -r "IP" cdr / 173 / *

c) Vamos supor que temos 1000 arquivos e queremos pesquisar apenas tipos específicos de arquivos. grep -r "IP" cdr / 173/07 / cdr_2018_07 * -e grep "IP" cdr / 173/06 / cdr_2018_06 *

    
por 02.08.2018 / 08:53