Imprime o conteúdo do primeiro arquivo que contém algumas cadeias específicas

1

Estou procurando um comando que imprima o conteúdo do primeiro arquivo encontrado em / etc que contenha uma string 10.17.1 ou 130.236.189 em que os comandos que precisam ser usados são: find , grep , head , xargs e cat .

O que eu alcancei antes da resposta de Ravexina e com alguma ajuda foi algo como o abaixo.

sudo egrep –rl '(10.17.1|130.236.189)' /etc | head -1 | cat
    
por NSH 15.04.2017 / 21:49

3 respostas

2

Eu iria com isso:

grep  -lRE  '10.17.1|130.236.189' /etc/ | head -1 | xargs cat
  • grep é usado com -R para pesquisar /etc recursivamente enquanto usa -E para usar recursos estendidos do grep.
  • A opção -l com grep é usada para imprimir apenas os nomes de arquivos em vez de conteúdo.
  • Em seguida, canalize-o para xargs e xargs forneça o nome do arquivo como parâmetro para cat
  • Depois de tudo gato irá imprimi-lo.

Se você tiver que usar find :

find /etc/ 2> /dev/null | xargs grep -lE '10.17.1|130.236.189' 2> /dev/null | head -1 | xargs cat

Eu usei 2> /dev/null para ignorar erros de permissão, quando sou um usuário comum, se você estiver usando sudo , não há necessidade de usá-los;)

    
por Ravexina 15.04.2017 / 22:00
2

Acho que você pode evitar o head e o xargs usando status de saída de grep como predicado lógico no comando find , por exemplo

find /etc -type f -exec grep -IFq -e '10.17.1' -e '130.236.189' {} \; -exec cat {} \; -quit

Explicação dos grep flags:

  • -I ignora os arquivos binários (geralmente não quer ficar com esses)
  • -F trata os padrões como sequências fixas em vez de expressões regulares (evita a necessidade de escapar dos períodos - às custas de não poder usar o operador regex | )
  • -q sai imediatamente com status zero se alguma correspondência for encontrada

O primeiro arquivo no qual grep encontra uma correspondência fará com que ela saia com status zero, o que, por sua vez, fará com que find execute o cat nesse arquivo. Supondo que cat seja bem-sucedido, find será então quit , de modo que apenas o conteúdo do primeiro arquivo correspondente seja impresso.

    
por steeldriver 15.04.2017 / 22:45
0

Veja o que eu faria:

$ find -type f -exec bash -c 'grep -q "10\.17\.1\|130\.236\.189" "" && printf "\n>>> \n" && cat ""' sh {} \;

A maneira como isso funciona é basicamente assim:

  • deixamos find manipular os arquivos de localização ( -type f ) e, para cada um deles, executar um comando usando -exec ... {}\; flag
  • esse comando específico estará no formato bash -c 'command1;command2' arg1 arg2
  • cada arquivo encontrado é passado como argumento para bash -c e dentro do próprio comando ele é referenciado como variable
  • grep -q verificará silenciosamente o arquivo para a expressão regular básica 10\.17\.1\|130\.236\.189 e sairá com 0 se o texto for encontrado ou 1, se não for encontrado.
  • após a descoberta bem-sucedida do texto, imprimimos o nome do arquivo usando o comando printf e, em seguida, cat do arquivo.

Execução de teste:

$ find -type f -exec bash -c 'grep -q "10\.17\.1\|130\.236\.189" "" && printf "\n>>> \n" && cat ""' sh {} \;

>>> ./somefile.txt
10.17.1
some other text
>>> ./somefile2.txt
another file, 130.236.189
some other text
    
por Sergiy Kolodyazhnyy 15.04.2017 / 22:59