2011-09-27 14 views
93

mi piacerebbe modificare un file con sed su OS X. Sto utilizzando il seguente comando:In-luogo le modifiche con sed su OS X

sed 's/oldword/newword/' file.txt 

l'output viene inviato al terminale. file.txt non modificato. Le modifiche vengono salvate file2.txt con questo comando:

sed 's/oldword/newword/' file1.txt > file2.txt 

Tuttavia non voglio un altro file. Voglio solo modificare file1.txt. Come posso fare questo?

Ho provato il flag -i. Il risultato è il seguente errore:

sed: 1: "file1.txt": invalid command code f 
+2

Qual è il comando esatto che si sta utilizzando quando si tenta la bandiera '-i'? – eldarerathis

risposta

191

È possibile utilizzare il flag -i correttamente, fornendo con un suffisso da aggiungere al file di backup. Estendere il tuo esempio:

sed -i.bu 's/oldword/newword/' file1.txt 

vi darà due file: uno con il nome file1.txt che contiene la sostituzione, e uno con il nome file1.txt.bu che ha il contenuto originale.

Moderatamente pericoloso

Se si vuole distruttivo sovrascrivere il file originale, usare qualcosa come:

sed -i '' 's/oldword/newword/' file1.txt 
    ^note the space 

A causa del modo in cui la linea di viene analizzato, è necessario uno spazio tra il flag di opzione e il suo argomento perché l'argomento è a lunghezza zero.

Oltre a cestinare il tuo originale, non sono a conoscenza di ulteriori pericoli di ingannare in questo modo. Va notato, tuttavia, che se questa invocazione di sed è parte di uno script, Unix Way ™ (IMHO) deve utilizzare sed in modo non distruttivo, verificare che sia stato chiuso in modo pulito e solo successivamente rimuovere il file esterno.

+0

Hai ragione, stavo omettendo l'estensione dopo il flag -i. È '-i''' pericoloso per qualsiasi motivo se non quello di incasinare il file originale (e non avere back-up)? – SundayMonday

+0

In base alla pagina man di 'sed' se si esaurisce lo spazio su disco sul dispositivo si potrebbe corrompere un file a metà strada e avere un risultato di output errato. Se stai lavorando sotto il controllo del codice locale 'sed -i" "' senza backup dovrebbe andare bene la maggior parte del tempo (o semplicemente 'git init && git add -A. && git commit -m 'backup'' prima di eseguire sed in Modalità '-i'). – cfeduke

+1

Ho trovato il bit leggermente pericoloso particolarmente utile. +1 – Andre

12

ho problema simile con MacOS

sed -i '' 's/oldword/newword/' file1.txt 

non lo fa opere, ma

sed -i"any_symbol" 's/oldword/newword/' file1.txt 

funziona bene.

2

È possibile utilizzare -i'' (--in-place) per sed come già suggerito. Vedere: The -i in-place argument, tuttavia, l'opzione -i è di estensione FreeBSD non standard e potrebbe non essere disponibile su altri sistemi operativi. In secondo luogo sed is a Stream EDitor, not a file editor.


modo alternativo è quello di utilizzare la sostituzione built-in in modalità Vim Ex, come:

$ ex +%s/foo/bar/g -scwq file.txt 

e per più-files:

$ ex +'bufdo!%s/foo/bar/g' -scxa *.* 

Per modificare tutti i file in modo ricorsivo voi possibile utilizzare **/*.* se la shell supporta quello (abilitare per shopt -s globstar).


Un altro modo è quello di utilizzare gawk e il suo nuovo "inplace" extension come ad esempio:

$ gawk -i inplace '{ gsub(/foo/, "bar") }; { print }' file1