Tentando adicionar vários comandos grep dentro de um exec

0

Eu estou tentando pesquisar todos os arquivos em um diretório (e todos os subdiretórios) para uma string. Se o arquivo tiver essa string, então eu quero procurar o número de vezes que outra string ocorre, neste caso "snake" e a saída. Eu também gostaria de produzir as linhas em que "cobra" ocorre dentro do arquivo.

echo "Files with Reptile:"
find . -type f -name "*.txt" -exec grep -l "Reptile" {} \;

Meu desafio é como adicionar comandos grep adicionais após as chaves. Eu tentei algumas coisas e continuo recebendo um erro "missing argument to -exec".

Estou tentando encher demais esse achado?

Obrigado

    
por Aldernat 09.11.2017 / 01:43

3 respostas

1

Você pode tentar o seguinte:

$ find . -type f -name "*.txt" -exec sh -c "grep -l "Reptile" {} | xargs -I% grep -Hn snake %" \;
./rep1.txt:2:snake
./rep2.txt:5:another snake

A saída contém listas delimitadas por dois pontos em que o primeiro argumento é o nome do arquivo (do argumento -H para grep ), o segundo argumento é o número da linha na qual o termo desejado aparece (do -n argumento para grep ), e o terceiro argumento é a própria linha.

O xargs pode ser movido para fora do find , fornecendo:

$ find . -type f -name "*.txt" -exec grep -l "Reptile" {} \; | xargs -i grep -Hn snake {}

Observe que o argumento -i para xargs (que é equivalente a -I{} está obsoleto, mas eu o uso com frequência por conveniência.

Arquivos de entrada:

$ tail -n+1 rep*.txt
==> rep1.txt <==
Reptile
snake
iguana
crocodile

==> rep2.txt <==
Reptile
alligator
turtle
another snake
komodo dragon

==> rep3.txt <==
Reptile
lizard
gecko

Se você precisa lidar com nomes de arquivos malformados, pode pensar em incorporar print0 e a opção -0 em xargs.

    
por 09.11.2017 / 01:58
1

Vários predicados -exec . Como -exec só é verdadeiro se o comando for bem-sucedido, não é necessário fazer nada de especial com o primeiro grep .

find ... -exec grep -q "Reptile" {} \; -exec grep -Hn snake {} \;
    
por 09.11.2017 / 02:11
0
find . -type f -name "*.txt" -exec sh -c 't=$(mktemp)
        for fi
        do
                if grep -q Reptile "$fi"
                then
                        echo "$fi contains Reptile"
                        grep snake "$fi" | tee "$t"
                        echo "snake appeared on $(wc -l < "$t") line(s)"
                fi
        done
        rm -f "$t"
        ' sh {} +

Isso informa os nomes dos arquivos que contêm a palavra / string “Reptile”, mesmo que eles não contenham a palavra "cobra", e relata de forma independente o número de linhas que contêm "cobra".

Opa; Eu interpretei mal a pergunta e pensei que isso fosse um requisito. Tirá-lo é fácil:

find . -type f -exec sh -c '
        for fi
        do
                if grep -q Reptile "$fi"
                then
                        echo "$fi contains Reptile"
                        grep snake "$fi"
                fi
        done
        ' sh {} +

Você pode adicionar uma opção -n ao grep snake , se desejar.

Isso deve tratar praticamente qualquer nome de arquivo válido. Verifique a (s) outra (s) resposta (s) com nomes de arquivos que começam com espaço e / ou contendo nova linha.

    
por 09.11.2017 / 02:05