Ho un file 'test' in linux con i seguenti dati.
aaaaaa
bbbbbb
cccccc
dddddd
eeeeee
Ho bisogno di tagliare l'ultima riga di questo file e metterlo in seconda posizione. Deve apparire come sotto.
aaaaaa
eeeeee
bbbbbb
cccccc
dddddd
Ho un file 'test' in linux con i seguenti dati.
aaaaaa
bbbbbb
cccccc
dddddd
eeeeee
Ho bisogno di tagliare l'ultima riga di questo file e metterlo in seconda posizione. Deve apparire come sotto.
aaaaaa
eeeeee
bbbbbb
cccccc
dddddd
Risposte:
Questo problema potrebbe effettivamente essere più semplice da gestire ed, dal momento che è fondamentalmente un editor di testo utilizzabile tramite script, piuttosto che un processore di flusso. Utilizzando ed, non è necessario salvare tutte le righe del file in un array, ad esempio, poiché lo sta già facendo per te.
# Create test file
~> printf "%s\n" aaaaaa bbbbbb cccccc dddddd eeeeee >test.txt
~> cat test.txt
aaaaaa
bbbbbb
cccccc
dddddd
eeeeee
# Use ed to open the file, move the last line after the first, save, and quit
~> printf "%s\n" '$m1' wq | ed test.txt
35
35
~> cat test.txt
aaaaaa
eeeeee
bbbbbb
cccccc
dddddd
sed '$x;1!H;1p;$!d;x;s/\n//
' <<\IN
aaaaaa
bbbbbb
cccccc
dddddd
eeeeee
IN
... che Hinvecchierà ogni riga che !non è la prima, e la prima che pstrappa. Nella $ultima riga It E xmodifiche tengono struttura modello prima fa il Hvecchio - che ottiene i righe salvate allegate all'ultima linea - poi deletes dall'uscita tutte le linee che sono !non l' $ultimo.
Sulla $ultima linea ë xancora modifiche spazi, s///ubstitutes via il primo \ncarattere ewline - che si prende cura di extra aggiunto sulla linea 2 - quindi autoprints del lotto.
aaaaaa
eeeeee
bbbbbb
cccccc
dddddd
cat <<\IN >infile
aaaaaa
bbbbbb
cccccc
dddddd
eeeeee
IN
... solo per salvare il tuo esempio in un file reale ...
sed '1p;$!d;r infile' <infile | sed '3d;$d'
Che reindirizza <infileai primi seds' stdin, che solo prints la prima linea prima dEliminazione dall'uscita tutte le linee che sono !non l' $ultima. L'ultima riga è autoprinted, ma è anche l'unica linea su cui viene eseguito il comando finale - vale a read l'intero infile nuovamente a stdout. Tutto ciò viene passato attraverso il |tubo al secondo sedche poi deve solo deliminare dalla sua uscita la sua terza e ultima linea di ingresso per completare la riorganizzazione.
aaaaaa
eeeeee
bbbbbb
cccccc
dddddd
awk- non ho mai provato. forse un giorno ...
Un approccio ingenuo usando awk:
~$ awk '{a[NR]=$0}END{print a[1];print a[NR];for(i=2;i<NR;i++){print a[i]}}' f
aaaaaa
eeeeee
bbbbbb
cccccc
dddddd
Memorizzi ogni riga anell'array, quindi stampi l'array nell'ordine desiderato (1a riga, ultima ( NR) e da 2 a penultima.
Usando una combinazione di testa / coda e sed:
~$ head -1 f;tail -1 f;sed '1d;$d' f
aaaaaa
eeeeee
bbbbbb
cccccc
dddddd
Stampa la prima riga, l'ultima e con sed elimina la prima e l'ultima.
Solo con sed, sono stato in grado di trovare solo questo comando. Sono sicuro che ci sono modi migliori:
~$ sed '${p;x;s/^\n//;p};2,${H;d}' f
aaaaaa
eeeeee
bbbbbb
cccccc
dddddd
Se è la prima riga, stampala (impostazione predefinita).
Dalla seconda riga, inseriscilo nel buffer di mantenimento ( H), ed eliminalo dallo spazio modello ( d). E se è l'ultima riga, stampala ( p), quindi ottieni il buffer di conservazione ( x), elimina la riga vuota ( s/^\n//) e stampala ( p).
sedparte sarebbe qualcosa di simile head -n -1 f | tail -n +2.
-1sintassi per headnon è portatile.
Con perl:
perl -e 'my @lines = <>; print for @lines[0, $#lines, 1..$#lines-1]' file
Con awk:
$ awk '
{lines[NR]=$0}
END{
print lines[1], lines[NR];
for (i=2; i<NR; i++) {print lines[i]}
}
' OFS=$'\n' file
PRODUZIONE
aaaaaa
eeeeee
bbbbbb
cccccc
dddddd
awksoluzioni, sei un grandesedfan o forse hai scrittosed? ;-)