Parte 1
d
Elimina semplicemente la tredicesima riga:
sed '13d' <file.txt
E un modo generale per fare il complemento di quanto sopra è:
sed '13!d' <file.txt
Parte 2
Perché può essere fatto:
sed -n ':a;${P;q};N;4,$D;ba' <file.txt
Nota che 4
è uno in più del numero richiesto. Quindi se volessi l'ultima riga 10, questo sarebbe 11
.
Test con seq
:
$ seq 100 | sed -n ':a;${P;q};N;4,$D;ba'
98
$
Tentativo di spiegazione
: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
La preziosa aggiunta di Glenn Jackman:
Quella era "solo l'ennesima riga". Ecco "all MA MA l'ennesima riga":
sed -n ':a;${s/^[^\n]*\n//;p;q};N;4,${P;D};ba'
funziona con GNU sed, la \n
sequenza potrebbe non funzionare con altri sed .
Ho provato questo con BSD sed (OSX) e ho scoperto che non funzionava abbastanza nel modulo sopra. I problemi sembrano essere:
;
usato per separare le linee sembra funzionare generalmente, ma non funziona dopo un'etichetta
- BSD sed sembra richiedere
;
dopo l'ultimo comando in un {}
gruppo di comandi a una riga , mentre GNU sed no
\n
può essere generalmente utilizzato nell'espressione regolare, ma apparentemente non all'interno di []
un'espressione tra parentesi. Quindi, per escludere le nuove righe, possiamo usare qualcosa di simile [[:alnum:][:punct:][:graph:][:blank:]]
, sebbene ciò possa escludere altri caratteri (in particolare altri caratteri di controllo).
Quindi questo è un tentativo di una versione più indipendente dalla piattaforma:
sed -n ':a
${s/^[[:alnum:][:punct:][:graph:][:blank:]]*\n//p;q;};N;4,${P;D;};ba'
Questo sembra funzionare sotto OSX e Ubuntu.
head
/tail
è molto più lenta di unased
soluzione. Grazie comunque.