Respostas:
Você pode usar isso para remover as duas primeiras linhas:
tail -n +3 foo.txt
e isso para remover as duas últimas linhas:
head -n -2 foo.txt
(supondo que o arquivo termine com \n
para o último)
Assim como para o uso padrão tail
e head
essas operações não são destrutivas. Use >out.txt
se você deseja redirecionar a saída para algum novo arquivo:
tail -n +3 foo.txt >out.txt
Caso out.txt
já exista, ele substituirá esse arquivo. Use em >>out.txt
vez de >out.txt
se preferir que a saída seja anexada out.txt
.
head -n -2
não é compatível com POSIX .
Se você deseja todas, exceto as primeiras linhas N-1, ligue tail
com o número de linhas +N
. (O número é o número da primeira linha que você deseja reter, iniciando em 1, ou seja, +1 significa iniciar no topo, +2 significa ignorar uma linha e assim por diante).
tail -n +3 foo.txt >>other-document
Não existe uma maneira fácil e portátil de pular as últimas N linhas. O GNU head
permite head -n +N
como contrapartida de tail -n +N
. Caso contrário, se você tiver tac
(por exemplo, GNU ou Busybox), poderá combiná-lo com a cauda:
tac | tail -n +3 | tac
Portably, você pode usar um filtro awk (não testado):
awk -vskip=2 '{
lines[NR] = $0;
if (NR > skip) print lines[NR-skip];
delete lines[NR-skip];
}'
Se você deseja remover as últimas linhas de um arquivo grande, pode determinar o deslocamento em bytes da peça a ser truncada e executar a truncagem com dd
.
total=$(wc -c < /file/to/truncate)
chop=$(tail -n 42 /file/to/truncate | wc -c)
dd if=/dev/null of=/file/to/truncate seek=1 bs="$((total-chop))"
Você não pode truncar um arquivo no lugar no início, mas se precisar remover as primeiras linhas de um arquivo enorme, poderá mover o conteúdo .
Na tail
página do manual (GNU tail
, ou seja):
-n, --lines=K
output the last K lines, instead of the last 10; or use -n +K to
output lines starting with the Kth
Portanto, o seguinte deve anexar todas, exceto as 2 primeiras linhas de somefile.txt
a anotherfile.txt
:
tail --lines=+3 somefile.txt >> anotherfile.txt
Para remover as primeiras n linhas, o GNU sed pode ser usado. Por exemplo, se n = 2
sed -n '1,2!p' input-file
A !
média "excluir este intervalo". Como você pode imaginar, resultados mais complicados podem ser obtidos, por exemplo
sed -n '3,5p;7p'
que mostrará a linha 3,4,5,7. Mais poder vem do uso de expressões regulares em vez de endereços.
A limitação é que os números das linhas devem ser conhecidos antecipadamente.
sed 1,2d
? Mais simples é geralmente melhor. Além disso, nada nos seus exemplos é específico ao GNU Sed; todos os seus comandos usam recursos padrão POSIX do Sed .
Embora tail -n +4
a saída do arquivo iniciando na 4ª linha (exceto as 3 primeiras) seja padrão e portátil, sua head
contraparte ( head -n -3
exceto todas as últimas 3 linhas) não é.
Portably, você faria:
sed '$d' | sed '$d' | sed '$d'
Ou:
sed -ne :1 -e '1,3{N;b1' -e '}' -e 'P;N;D'
(lembre-se de que em alguns sistemas onde sed
há um espaço padrão de tamanho limitado, isso não é dimensionado para valores grandes de n
).
Ou:
awk 'NR>3 {print l[NR%3]}; {l[NR%3]=$0}'
Espero ter entendido claramente sua necessidade.
Você tem várias maneiras de concluir sua solicitação:
tail -n$(expr $(cat /etc/passwd|wc -l) - 2) /etc/passwd
Onde / etc / passwd é seu arquivo
A segunda solução pode ser útil se você tiver um arquivo enorme:
my1stline=$(head -n1 /etc/passwd)
my2ndline=$(head -n2 /etc/passwd|grep -v "$my1stline")
cat /etc/passwd |grep -Ev "$my1stline|$my2ndline"
\n
" .. Ele funciona para todos os números inteiros negativos, exceto os-n -0
que não retornam nada , da mesma maneira que-n 0
faria (usando: head (GNU coreutils) 7.4) ... No entanto, quando um trailing\n
está presente,-n -0
é impresso como se poderia esperar do-
, ie. ele imprime o arquivo inteiro ... Então, ela não funciona para todos os valores negativos não-zero .. mas-0
falha quando não há nenhuma fuga\n