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 H
invecchierà ogni riga che !
non è la prima, e la prima che p
strappa. Nella $
ultima riga It E x
modifiche tengono struttura modello prima fa il H
vecchio - che ottiene i righe salvate allegate all'ultima linea - poi d
eletes dall'uscita tutte le linee che sono !
non l' $
ultimo.
Sulla $
ultima linea ë x
ancora modifiche spazi, s///
ubstitutes via il primo \n
carattere 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 <infile
ai primi sed
s' stdin
, che solo p
rints la prima linea prima d
Eliminazione 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 r
ead l'intero infile
nuovamente a stdout
. Tutto ciò viene passato attraverso il |
tubo al secondo sed
che poi deve solo d
eliminare 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 a
nell'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
).
sed
parte sarebbe qualcosa di simile head -n -1 f | tail -n +2
.
-1
sintassi per head
non è 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
awk
soluzioni, sei un grandesed
fan o forse hai scrittosed
? ;-)