Qual è il significato di: a; $! N; in un comando sed?


11
$ (echo hello; echo there) | sed ':a;$!N;s/\n/string/;ta'
hellostringthere

Il sedcomando precedente sostituisce il nuovo carattere di riga con la stringa "stringa". Ma non conosco il significato delle :a;$!N;s/\n/string/;tavirgolette singole. Conosco la parte centrale s/\n/string/. Ma non conosco la funzione di first ( :a;$!N;) e last ( ta) part.



E l'ultima parte?
Avinash Raj,

Il comando "t" si dirama verso un'etichetta denominata se l'ultimo comando sostitutivo ha modificato lo spazio modello.
xiaodongjie,

Risposte:


17

Questi sono, certamente, criptici, sedcomandi. In particolare (da man sed):

: etichetta
         Etichetta per i comandi b e t.

t label
         Se as /// ha eseguito correttamente una sostituzione dall'ultima riga di input e dall'ultimo comando t o T, quindi passare all'etichetta; se l'etichetta viene omessa, dalla fine alla fine dello script.

n N Leggi / aggiungi la riga successiva di input nello spazio modello.

Quindi, lo script che hai pubblicato può essere suddiviso in (spazi aggiunti per la leggibilità):

sed ':a;  $!N;  s/\n/string/;  ta'
     ---  ----  -------------  --
      |     |        |          |--> go back (`t`) to `a`
      |     |        |-------------> substitute newlines with `string`
      |     |----------------------> If this is not the last line (`$!`), append the 
      |                              next line to the pattern space.
      |----------------------------> Create the label `a`.

Fondamentalmente, ciò che sta facendo potrebbe essere scritto in pseudocodice come

while (not end of line){
    append current line to this one and replace \n with 'string'
}

Puoi capirlo un po 'meglio con un esempio di input più complesso:

$ printf "line1\nline2\nline3\nline4\nline5\n" | sed ':a;$!N;s/\n/string/;ta'
line1stringline2stringline3stringline4stringline5

Non sono davvero sicuro del motivo per cui !$è necessario. Per quanto ne so, puoi ottenere lo stesso output con

printf "line1\nline2\nline3\nline4\nline5\n" | sed ':a;N;s/\n/string/;ta'

1
Il! $ È di non corrispondere all'ultima riga, IMO.
Braiam,

@Braiam non ne è troppo sicuro, non lo $!è !$. Tuttavia, potrebbe anche essere !Ne non $!.
terdon,

Stavo cercando di analizzare la pagina texinfo ma non ho trovato riferimenti a nessuno dei due !No $!. Quindi, continuo a pensare che se l'ultima riga è newline o EOF.
Braiam,

4
Provo a pensare $!a un 'intervallo' di indirizzi con un operatore di complemento postfix - quindi $!N(fare Novunque tranne l'indirizzo $) è davvero la stessa sintassi di qualcosa del tipo m,n!d(elimina tutto tranne le righe min n).
steeldriver,

:è un analogo gotodell'etichetta, e in effetti :era un'etichetta goto nella shell Thompson, quindi sarebbe familiare alle persone che usavano sed e shell Thompson
Sergiy Kolodyazhnyy

0

Pubblico questa risposta poiché vedo molta confusione sul perché l'ultima riga è esclusa durante l'esecuzione N(attraverso la stringa di indirizzamento della riga $!) e perché l'OP era confuso sul significato di :a;$!N; in un comando sed , non solo in quello specifico che ha pubblicato .

Bene, il vantaggio di usare $!Ninvece di Nnon è evidente negli esempi proposti (dall'OP e da @terdon), poiché nessun comando "importante" (continua a leggere) viene eseguito sull'ultima riga dopo il Ncomando. (In effetti, il risultato è lo stesso se si toglie l'indirizzo di quella linea.)

In un esempio più complesso (ad esempio, sostituire this sentencein un file, con le due parole che appaiono talvolta su una riga e altre volte su due righe), escludere l'ultima riga per il Ncomando potrebbe essere cruciale! Se l'ultima riga non viene esclusa, una volta eseguita Nsu di essa, sedcolpisce EOFimmediatamente ed esce immediatamente, impedendo l' esecuzione di tutti i comandi successivi (anche i comandi di ramificazione, vale a dire te b).

Negli esempi troppo semplicistici mostrati, possiamo tranquillamente rimuovere $!e lasciare sedfallire nell'esecuzione Ne nel ritorno poiché il scomando interrotto non farebbe nulla se fosse eseguito, dal momento che non vi è alcuna \ncorrispondenza.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.