Parte 1
Simplesmente d
elimine a 13ª linha:
sed '13d' <file.txt
E uma maneira geral de fazer o complemento acima é:
sed '13!d' <file.txt
Parte 2
Porque isso pode ser feito:
sed -n ':a;${P;q};N;4,$D;ba' <file.txt
Observe que 4
é um a mais que o número necessário. Então, se você quisesse a última linha 10, seria 11
.
Testando com seq
:
$ seq 100 | sed -n ':a;${P;q};N;4,$D;ba'
98
$
Tentativa de explicação
:a # define label a
${ # match the last line
P # print the first line of the pattern space
q # quit
}
N # match all lines: append the next line to the pattern
4,${ # match the range of lines 4 to the end of the file
D # delete the first line of the pattern space
}
ba # match all lines: jump back to label a
A valiosa adição de Glenn Jackman:
Essa foi "apenas a enésima linha". Aqui está "tudo, mas a enésima linha":
sed -n ':a;${s/^[^\n]*\n//;p;q};N;4,${P;D};ba'
funciona com o GNU sed, a \n
sequência pode não funcionar com outros seds.
Eu tentei isso com o BSD sed (OSX) e constatei que não funcionava exatamente na forma acima. Os problemas parecem ser:
;
usado para separar linhas geralmente parece funcionar, mas não funciona após um rótulo
- O BSD sed parece requerer
;
após o último comando em um {}
grupo de comandos de uma linha , enquanto o GNU sed não requer
\n
geralmente pode ser usado dentro da expressão regular, mas aparentemente não dentro de uma []
expressão entre colchetes. Portanto, para excluir novas linhas, podemos usar algo como isso [[:alnum:][:punct:][:graph:][:blank:]]
, embora isso possa excluir outros caracteres (especificamente outros caracteres de controle).
Portanto, esta é uma tentativa de uma versão mais independente da plataforma:
sed -n ':a
${s/^[[:alnum:][:punct:][:graph:][:blank:]]*\n//p;q;};N;4,${P;D;};ba'
Isso parece funcionar no OSX e no Ubuntu.
head
/tail
é muito mais lenta que umased
solução. Obrigado embora.head
/tail
) são otimizados para fazer o que fazem.