Aplicando a cabeça do Unix no Awk através do comando de encontro
Pergunta
Quero produzir as 10 principais linhas de comando AWK na lista de arquivos fornecidos pelo Find, usando este snippet:
$ find . -name "*.txt" -print -exec awk '$9 != ""' \| head -n10 {} \;
Observe também que quero imprimir os nomes de arquivos que estão sendo processados.
Mas por que recebo esse erro:
awk: cmd. line:2: fatal: cannot open file `|' for reading (No such file or directory)
./myfile.txt
Qual é a maneira certa de fazer isso?
Eu tentei sem barragem antes do tubo. Ainda assim deu um erro:
find: missing argument to `-exec'
head: cannot open `{}' for reading: No such file or directory
head: cannot open `;' for reading: No such file or directory
Solução
Se você deseja executar um programa AWK em todos os arquivos do Find, que apenas imprime as 10 primeiras linhas cada vez.
$ find . -name "*.txt" -print -exec awk '$9 != "" && n < 10 {print; n++}' {} \;
Outras dicas
Ao executar um comando com o Find's -exec, você não obtém todas as coisas legais, como o operador do tubo (|). Você pode recuperá -los executando explicitamente uma subshell, se quiser, por exemplo:
achar . -name '*.txt' -exec /bin /sh -c "ecoa um arquivo de texto chamado {} | head -n 15" ;
Baseado na resposta de Ashawley:
find . -name "*.txt" -print -exec awk '$9 != "" {print; if(NR > 9) exit; }' {} \;
Deve ter um desempenho melhor, à medida que saímos de Awk após o 10º recorde.
Usando awk
Só deve funcionar:
find . -name "*.txt" -print -exec awk '{if($9!=""&&n<11){print;n++}}' {} \;
Você pode fazer desta maneira também:
find . -name '*txt' -print -exec awk 'BEGIN {nl=1 ;print FILENAME} $9 !="" {if (nl<11) { print $0 ; nl = nl + 1 }}' {} \;
sem head
.