Esta tarefa é mais facilmente realizada processando as linhas do arquivo na ordem oposta.
tac infile | awk 'flag {print} {if(NF) flag=1}' | tac | sponge infile
Como apontado nos comentários de Malte Skoruppa e zwets, o Ubuntu não vem com o pacote moreutils
pré-instalado, que contém sponge
; uma solução alternativa é usar uma substituição de comando dentro de um travessão para ler o arquivo de entrada, para que, sendo a substituição do comando processada primeiro, o arquivo seja seguro para ser truncado pelo segundo comando tac
:
<<<"$(< infile)" tac | awk 'flag {print} {if(NF) flag=1}' | tac > infile
-
tac infile
: ... faz o oposto decat infile
(!): imprime o arquivo emstdout
invertendo a ordem da linha; -
awk [...]
: processa o arquivo; -
tac
: ... faz o oposto decat
(!): imprime o arquivo emstdout
invertendo a ordem da linha; -
sponge infile
: envia parainfile
apenas quando o lado esquerdo do canal terminou sua execução, para evitar truncarinfile
antes de ser lido pelo primeiro comandotac
;
% de colapso do comandoawk
:
-
flag {print}
: seflag
estiver definido, a linha será impressa;flag
não será definido até que um registro cujoNF
corresponda a um número maior que0
seja processado, portanto, até que um registro cujo valorNF
corresponda a um número maior que0
não encontrado, a% O comandoprint
será ignorado; -
{if(NF) flag=1}
: se enquantoflag
ainda não foi definido um registro cujoNF
corresponde a um número maior que0
é processado, ele não será impresso eflag
será definido como1
, então o primeiro registro cujo valorNF
corresponde a um número maior que0
não será impresso;
Teste em um arquivo de teste (lembre-se de que a linha 4 e a linha 7 contêm 5 espaços, enquanto a linha 5 e a linha 8 estão vazias):
user@debian ~ % cat infile
line1
line2
line3
line6
user@debian ~ % tac infile | awk 'flag {print} {if(NF) flag=1}' | tac
line1
line2
line3
user@debian ~ %
A linha 7 e a linha 8 foram removidas porque estavam ambas no final do arquivo, contendo apenas espaços (linha 7) ou contendo nada (linha 8); a linha 6 foi excluída porque foi a primeira, lendo as linhas do arquivo na ordem oposta, para ter pelo menos um campo (portanto, não estando vazio ou contendo apenas espaços)