La mia domanda riguarda il sed
-soluzione specifica data in questa risposta per questa domanda di grepping inverso. Il sed
/grep
la soluzione che non riesco a decifrare è la seguente:
sed '1!G;h;$!d' file
Qualcuno può decifrare questo comando?
So dalla conoscenza di VI(M) che G denota l'ultima riga del file e che in sed a bang(!) seguito da un indirizzo funziona un po' come grep -v
vale a dire che non corrisponderà a quella linea. Ma nel complesso lo script sed inline sopra è al di là di me.
Risposta accettata:
Questo inverte il file riga per riga.
sed '1!G;h;$!d' file
Innanzitutto, sed
ha uno spazio di attesa e uno spazio modello . Dobbiamo distinguerli prima di concentrarci su quel comando specifico.
Quando sed
legge una nuova riga, viene caricata nello spazio pattern. Pertanto, quello spazio viene sovrascritto ogni volta che viene elaborata una nuova riga. D'altra parte, lo spazio di attesa è coerente durante l'intera elaborazione e i valori possono essere archiviati lì per un utilizzo successivo.
Al comando:
Ci sono 3 comandi in questa istruzione:1!G
, h
e $!d
-
1!G
significa che ilG
il comando viene eseguito su ogni riga tranne la prima (il!
nega il1
).G
significa aggiungere cosa c'è nello spazio di attesa nello spazio del modello. -
h
vale per ogni riga. copia lo spazio del modello nello spazio di attesa (e lo sovrascrive). -
$!d
si applica a tutte le righe tranne l'ultima ($
rappresenta l'ultima riga,!
lo nega).d
è il comando per eliminare la riga (spazio pattern).
- Ora, quando viene letta la prima riga,
sed
esegue ilh
comando. La prima riga viene copiata nello spazio di attesa. Quindi viene eliminato, poiché corrisponde a$!
condizione.sed
continua con la seconda riga. - La seconda riga corrisponde alla condizione
1!
(non è la prima riga), quindi lo spazio di attesa (che ha la prima riga) viene aggiunto allo spazio del modello (che ha la seconda riga). Dopodiché, nello spazio del modello, c'è ora la seconda riga seguita dalla prima riga, delimitata da una nuova riga. Ora, ilh
il comando si applica (come in ogni riga); tutto ciò che è nello spazio del modello viene copiato nello spazio di attesa. La terza istruzione ($!d
) si applica:la linea viene eliminata dallo spazio del modello. - Il passaggio 2 è ora terminato con tutte le righe. Saliamo all'ultima riga.
- Nell'ultima riga (
$
) quasi tutto il passaggio 2 è terminato, ma non la parte di eliminazione (d
).sed
, quando invocato senza-n
, stampa automaticamente lo spazio del modello al termine dell'elaborazione per ciascuna riga di input. Quindi, quando non viene eliminato, viene stampato lo spazio del motivo. Ora contiene tutte le righe in ordine inverso .