sed cerca e sostituisce stringhe contenenti /

Ho difficoltà a capire come usare sed per cercare e sostituire stringhe contenenti il ​​carattere / in un file di testo /etc/myconfig .

Ad esempio, nel mio file di testo esistente, ho:

 myparam /path/to/a argB=/path/to/B xo 

e voglio questo sostituito da:

 myparam /path/to/c argB=/path/to/D xo 

Ho provato a farlo in bash:

 line='myparam /path/to/a argB=/path/to/B xo' line_new='myparam /path/to/c argB=/path/to/D xo' sed -i 's/$line/$line_new/g' /etc/myconfig 

Ma non succede nulla.

tentare

 grep -rn "$line" /etc/myconfig 

mi restituisce 'myparam /path/to/a argB=/path/to/B xo' .

Qual è il modo corretto di esprimere il mio comando sed per eseguire questa ricerca e sostituire e gestire correttamente il comando / ? (Suppongo che il carattere / nelle mie stringhe sia quello che mi dà il problema perché ho usato un comando sed simile per cercare e sostituire un’altra riga nel file di testo senza problemi e quella linea non ha un carattere / .

Non sfuggire ai backslash; ti confonderai. Usa un simbolo diverso dopo il comando s che non appare nel testo (sto usando % nell’esempio sotto):

 line_old='myparam /path/to/a argB=/path/to/B xo' line_new='myparam /path/to/c argB=/path/to/D xo' sed -i "s%$line_old%$line_new%g" /etc/myconfig 

Inoltre, racchiudi l’intera stringa tra virgolette; l’uso di virgolette singole significa che sed vede $line (nell’originale) invece del valore espanso. All’interno delle virgolette singole, non c’è espansione e non ci sono metacaratteri. Se il tuo testo può contenere quasi tutti i caratteri di testo normale, usa un carattere di controllo (ad esempio control-A o control-G) come delimitatore.

Si noti che l’uso di -i qui riflette ciò che è nella domanda, ma che presuppone l’uso di GNU sed . Anche BSD sed (disponibile su Mac OS X) richiede un suffisso. Puoi usare sed -i '' … per sostituire in situ; che non funziona con GNU sed . Per essere portabile tra i due, usa -i.bak ; che funzionerà con entrambi, ma ti fornirà un file di backup che probabilmente vorrai eliminare. Altre piattaforms Unix (ad es. AIX, HP-UX, Solaris) possono avere varianti di sed che non supportano -i affatto. Non è richiesto dalle specifiche POSIX per sed .

Questo potrebbe funzionare per te:

 sed -i "s|$line|$line_new|g" /etc/myconfig 

È necessario utilizzare " ” in modo che la $line e $new_line siano interpolate.Inoltre utilizzare | o qualsiasi carattere non trovato nella corrispondenza o nelle stringhe di sostituzione come delimitatore.