Parte 1
Simplesmente d
elete a 13ª linha:
sed '13d' <file.txt
E uma maneira geral de fazer o complemento dos itens 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 desejado. Então, se você quisesse a última 10ª linha, isso seria 11
.
Teste 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
Adição valiosa 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 sequência \n
pode não funcionar com outros seds.
Eu tentei isso com o BSD sed (OSX) e achei que não funcionava bem na forma acima. Os problemas parecem ser:
-
;
usado para separar linhas parece funcionar geralmente, mas não funciona depois de um rótulo - O BSD sed parece exigir
;
após o último comando em um grupo de comando{}
de uma linha, enquanto o sed GNU não -
\n
geralmente pode ser usado dentro da expressão regular, mas aparentemente não dentro de uma expressão de parêntese[]
. Então, para excluir novas linhas, podemos usar algo como[[:alnum:][:punct:][:graph:][:blank:]]
, embora isso possa excluir outros caracteres (especificamente outros caracteres de controle).
Portanto, esta é uma tentativa de uma versão independente de 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.