Digamos que eu precise apenas das 5 primeiras linhas de uma saída para fins de registro. Também preciso saber se e quando o log foi truncado.
Estou tentando usar head
para fazer o trabalho, o seq
comando abaixo gera 20 linhas que são truncadas por head
, e eu echo
uma informação de truncamento:
> seq -f 'log line %.0f' 20 | head -n 5 && echo '...Output truncated. Only showing first 5 lines...'
log line 1
log line 2
log line 3
log line 4
log line 5
...Output truncated. Only showing first 5 lines...
Mas se o seq
comando gerar menos de 5 linhas, usando a mesma construção acima, recebo um status "truncado" errado:
seq -f ' log line %.0f' 3 | head -n 5 && echo '...Output truncated. Only showing first 5 lines...'
log line 1
log line 2
log line 3
...Output truncated. Only showing first 5 lines...
Existe uma maneira de o head
comando (ou outra ferramenta) me dizer se truncou alguma coisa para que eu exiba apenas a mensagem "... truncado ..." quando necessário?
Uma nota de advertência:
Quando você faz:
e se a saída for truncada, isso pode causar
cmd
a morte de um SIGPIPE, se ele escrever mais linhas depoishead
de sair. Se não for o que você deseja, se quisercmd
continuar executando depois, mesmo que sua saída seja descartada, você precisará ler, mas descartar as linhas restantes, em vez de sair após a saída de 10 linhas (por exemplo, comsed '1,10!d'
ouawk 'NR<=10'
em vez dehead
).Então, para as duas abordagens diferentes:
saída truncada, cmd pode ser morto
Observe que a
mawk
implementação deawk
acumula um buffer cheio de entrada antes de iniciar o processamento, portanto,cmd
não pode ser encerrada até que tenha gravado um buffer cheio (8KiB no meu sistema AFAICT) de dados. Isso pode ser contornado usando a-Winteractive
opção.Algumas
sed
implementações também lêem uma linha com antecedência (para poder saber qual é a última linha ao usar o$
endereço), portanto, com essas,cmd
só pode ser morto após ter emitido sua 7ª linha.saída truncada, o restante descartado para que o cmd não seja eliminado
Você pode usar o AWK:
Isso imprime as primeiras cinco linhas (se houver) como estão; se vir uma linha além disso, ele emite a mensagem de truncamento e sai.
Você pode especificar o código de saída a ser usado, se desejar implementar o processamento condicional: