Excluir última linha do arquivo

44

Eu uso sed para excluir rapidamente linhas com posição específica como

sed '1d'
sed '5d'

Mas, e se eu quiser excluir a última linha do arquivo e não souber a contagem de linhas (eu sei que posso usar isso wce vários outros truques).

Atualmente, usando uma solução alternativa com heade tailcombinada com wcpara fazer isso. Alguma reviravolta rápida aqui?

mtk
fonte
Qual sistema operacional? Alguns sabores têm opções interessantes para heade tail...
Nils
@ Nils Estou no 'Red Hat Enterprise Linux Server versão 5.5 (Tikanga)'. Você pode apontar as opções heade tailconhecer diferentes sabores?
mtk
Eu fiz. Ver abaixo.
Nils

Respostas:

88

in sed $é a última linha, portanto, para excluir a última linha:

sed '$d' <file>
h3rrmiller
fonte
12
Use sed -i '$d' <file>para editar o arquivo no local.
WanderingMind
1
O que seria para excluir as últimas n linhas, onde n é qualquer número inteiro?
Joshua Salazar
31

$ para a última linha:

sed '$d' file
Guru
fonte
10
vencê-lo por 30 segundos: P
h3rrmiller 24/10/12
1
Infelizmente, é preciso usar técnicas mais complexas para excluir, digamos, as duas últimas linhas.
dubiousjim
O que você quer dizer? sed '$d' file; sed '$d' file
24412 Rob
3
@ Rob: sed '$d' filena verdade, não modifica o arquivo; apenas imprime o conteúdo do arquivo, menos a última linha. Portanto sed '$d' file; sed '$d' file, imprimirá o conteúdo do arquivo duas vezes , menos a última linha de cada vez. O equivalente de excluir as duas últimas linhas de sed '$d' fileé sed '$d' file | sed '$d'.
Ruakh 24/10/12
2
Sim, isso é deselegante, mas é claro que funciona. Eu faria isso de uma só vez sed -n '1{h;n;}; $q; x; p;'. Eu estava fazendo beicinho que não podemos simplesmente fazer sed '$-1,$d'.
dubiousjim
14

cat file.txt | head -n -1 > new_file.txt

Cuidado, ao que parece, dependendo da última linha de file.txt(se terminar com EOF, ou \ne então EOF), o número de linhas em new_file.txtpode ser o mesmo (como file.txt) após este comando (isso acontece quando não há \n) - em qualquer caso, o conteúdo da última linha é excluído.

Além disso, observe que você deve usar um segundo arquivo (intermediário). Se você catar e redirecionar para o mesmo arquivo, você o apagará.

Emanuel Berg
fonte
6
Onde isso funciona, também pode ser simples head -n -1 file.txt > new_file.txt. Observe que as contagens negativas head -nestão disponíveis apenas para algumas implementações de head. Por exemplo, ele não funciona no FreeBSD ou na versão BusyBox do head.
dubiousjim
1
@dubiousjim: Concordo, head -n -1 file.txt > new_file.txté melhor. Funciona da mesma maneira com relação aos meus dois comentários (mesmo número de linhas e apagar no mesmo arquivo). Quanto ao argumento negativo, essas diferenças ocorrem de tempos em tempos entre os Unixes, e geralmente são frustrantes porque você espera que seja o mesmo comando inteiramente (e por que você não faria - mesmo nome e objetivo!) - de qualquer maneira, bom ponto. (Eu uso Debian.)
Emanuel Berg
5

head --lines=-1. Eu me deparei com essa possibilidade na página de manual de um sistema SLES11SP2 (coreutils-8.12-6.23.1)

taile headfazem parte do coreutils-rpm (pelo menos para sistemas baseados em rpm).

De acordo com o changelog do coreutils, esta sintaxe é suportada desde o coreutils-versão 5.0.1

Más notícias: De acordo com a RH5-man-page, esta opção não está descrita

Boas notícias: Funciona com o RH5 (portanto, no seu caso: funciona - pelo menos com uma versão atual do RH5).

rpm -q coreutils me mostra (no CentOS 5.8): coreutils-5.97-34.el5_8.1

Não tenho certeza se RH5.5. já possui a versão coreutils que a suporta. Mas 5.5 tem EoLed de qualquer maneira.

Nils
fonte
+1. funciona perfeitamente no RH5.5. Obrigado.
mtk
0

Linux

$ é a última linha, d para exclusão:

sed '$d' ~/path/to/your/file/name

Mac OS

Equivalente ao sed -i

sed -i '' -e '$ d' ~/path/to/your/file/name
jasonleonhard
fonte