2013-08-17 10 views
5

Vorrei solo sed l'ultimo modello di corrispondenza di un file di testo. file di inputsed solo l'ultimo modello di corrispondenza

:

boy 
boy 
girl 
boy 

file di output:

boy 
boy 
girl 
boys 
+1

http://stackoverflow.com/questions/17114807/sed-replace-last-line-matching-pattern –

risposta

7

Un metodo sarebbe per invertire il file, sostituire solo la prima corrispondenza, e poi invertire nuovamente indietro.

tac <file> | sed '1 s/boy/boys/' | tac | sponge <newfile> 

tac "concatena e stampa i file al contrario". sponge "assorbirà input standard e scriverà su un file". È nel pacchetto "moreutils" su debian.

+2

Qual è il vantaggio del piping su 'sponge' rispetto a' tac> newfile'? Lo svantaggio, se i dati sono grandi, è che c'è una pipa extra che i dati devono essere copiati dentro e fuori, il che rallenta le cose. –

+0

Proprio quello che le mie dita sono andato per come ho pensato al problema, davvero. Non è una soluzione robusta e universale, ti concedo. – chooban

6

Tutto ciò che serve è $:

sed '$s/boy/boys/' 
+5

Supponiamo che ci fosse un'altra "ragazza" dopo l'ultimo "ragazzo"? Funziona sui dati di esempio specifici, ma non più in generale. –

0

Questo potrebbe funzionare per voi (GNU sed):

sed '1h;1!H;$!d;x;s/.*boy/&s/' file 

Slurp il file in memoria e sostituiamo l'ultima occorrenza della stringa desiderata utilizzando l'avidità .

Un'alternativa, meno memoria soluzione intensiva:

sed '/.*boy/,$!b;//{x;//p;x;h};//!H;$!d;x;s//&s/' file 

Questo utilizza lo spazio stiva per contenere righe precedenti che contengono la stringa richiesta e sparge quando viene rilevato un nuovo occorrenza della stringa richiesta. Alla fine del file, l'ultima occorrenza si trova nello spazio di attesa e viene modificata.