Sumary
Sintassi GNU:
sed '/claudio/{s//claudia/;:p;n;bp}' file
O anche (per usare una sola volta la parola da sostituire:
sed '/\(claudi\)o/{s//\1a/;:p;n;bp}' file
Oppure, nella sintassi POSIX:
sed -e '/claudio/{s//claudia/;:p' -e 'n;bp' -e '}' file
funziona su qualsiasi sed, elabora solo tutte le righe necessarie per trovare la prima claudio, funziona anche se si claudiotrova nella prima riga ed è più corta in quanto utilizza solo una stringa regex.
Dettaglio
Per cambiare solo una riga devi selezionare solo una riga.
Usando un 1,/claudio/(dalla tua domanda) seleziona:
- dalla prima riga (incondizionatamente)
- alla riga successiva che contiene la stringa
claudio.
$ cat file
claudio 1
antonio 2
claudio 3
michele 4
$ sed -n '1,/claudio/{p}' file
claudio 1
antonio 2
claudio 3
Per selezionare qualsiasi riga che contiene claudio, utilizzare:
$ sed -n `/claudio/{p}` file
claudio 1
claudio 3
E per selezionare solo il primo claudio nel file, utilizzare:
sed -n '/claudio/{p;q}' file
claudio 1
Quindi, puoi effettuare una sostituzione solo su quella linea:
sed '/claudio/{s/claudio/claudia/;q}' file
claudia 1
Il che cambierà solo la prima occorrenza della corrispondenza regex sulla riga, anche se potrebbe essercene più di una, sulla prima riga corrispondente alla regex.
Naturalmente, il /claudio/regex potrebbe essere semplificato per:
$ sed '/claudio/{s//claudia/;q}' file
claudia 1
E, quindi, l'unica cosa che manca è stampare tutte le altre righe non modificate:
sed '/claudio/{s//claudia/;:p;n;bp}' file
info sed: (0,/REGEXP/: un numero di riga 0 può essere usato in una specifica di indirizzo come0,/REGEXP/quellasedche cercherà di far corrispondere REGEXP anche nella prima riga di input. In altre parole,0,/REGEXP/è simile a1,/REGEXP/, tranne per il fatto che se ADDR2 corrisponde alla prima riga di input, 0, / REGEXP / form lo considererà come fine dell'intervallo, mentre 1, / REGEXP / form corrisponderanno all'inizio del suo intervallo e quindi estenderanno l'intervallo fino alla seconda occorrenza dell'espressione regolare)