Só encontra os primeiros arquivos encontrados usando find?

17

Digamos que possa haver centenas de *.txt arquivos em um diretório. Eu só quero encontrar os primeiros três arquivos *.txt e, em seguida, sair do processo de pesquisa.

Como conseguir isso usando o utilitário find ? Eu passei rápido pela man page, não parecia uma opção para isso.

    
por mitnk 19.03.2013 / 09:19

2 respostas

22

Você pode canalizar a saída de find a head :

find . -name '*.txt' | head -n 3
    
por 19.03.2013 / 09:27
3

Esta outra resposta é um pouco falha. O comando é

find . -name '*.txt' | head -n 3

Depois, há uma explicação em um dos comentários [ênfase minha]:

head starts up and waits for input from the lefthand side of the pipe. Then find starts up and searches for files that match the criteria specified, sending its output through the pipe. When head has received and printed the number of lines requested, it terminates, closing the pipe. find notices the closed pipe and it also terminates. Simple, elegant and efficient.

Isso é quase verdadeiro.

O problema é que find percebe o canal fechado somente quando tenta gravar nele - nesse caso, é quando a quarta correspondência é encontrada. Mas se não houver uma quarta partida, então find continuará. Seu shell irá esperar! Se isso acontecer em um script, o script irá esperar, apesar do fato de que já sabemos que a saída do pipe é final e nada pode ser adicionado a ele. Não é tão eficiente.

O efeito é insignificante se esse find específico terminar rapidamente, mas com uma pesquisa complexa em uma árvore de arquivos grande, o comando pode atrasar desnecessariamente o que você quiser fazer em seguida.

A solução não tão perfeita é executar

( find … & ) | head -n 3

Dessa forma, quando head sair, o shell continuará imediatamente. O processo de background find pode ser ignorado (sairá mais cedo ou mais tarde) ou será segmentado com pkill ou algo assim.

Para provar o conceito, você pode pesquisar por / . Esperamos apenas um jogo, mas find procura em todos os lugares e isso pode levar muito tempo.

find / -wholename / 2>/dev/null | head -n 1

Finalize com Ctrl + C assim que você vir o problema. Agora compare:

pidof find ; ( find / -wholename / 2>/dev/null & ) | head -n 1 ; pidof find
    
por 23.06.2017 / 22:35

Tags