Modifiche sul posto con sed su OS X.


142

Vorrei modificare un file con sed su OS X. Sto usando il seguente comando:

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

L'output viene inviato al terminale. file.txt non è modificato. Le modifiche vengono salvate in 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 la bandiera -i. Ciò provoca il seguente errore:

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

2
Qual è il comando esatto che stai usando quando provi la -ibandiera?
eldarerathis,

Risposte:


282

È possibile utilizzare -icorrettamente il flag fornendo un suffisso da aggiungere al file di backup. Estensione del tuo esempio:

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

Ti daranno due file: uno con il nome file1.txtche contiene la sostituzione e uno con il nome file1.txt.buche ha il contenuto originale.

Leggermente pericoloso

Se si desidera sovrascrivere in modo distruttivo il file originale, utilizzare qualcosa del tipo:

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

A causa del modo in cui la riga viene analizzata, è necessario uno spazio tra il flag di opzione e il suo argomento poiché l'argomento è di lunghezza zero.

Oltre a rovinare il tuo originale, non sono a conoscenza di ulteriori pericoli di ingannare sed in questo modo. Va notato, tuttavia, che se questa invocazione sedfa parte di uno script, The Unix Way ™ dovrebbe (IMHO) essere utilizzato in modo sednon distruttivo, testare che sia uscito in modo pulito e solo successivamente rimuovere il file estraneo.


Hai ragione, stavo omettendo l'estensione dopo la bandiera -i. È -i''pericoloso per qualsiasi motivo se non quello di incasinare il file originale (e di non avere backup)?
Domenica,

Secondo la sedpagina man, se si esaurisce lo spazio su disco sul dispositivo, è possibile corrompere un file a mezza falcata e avere un risultato di output scadente. Se lavori sotto il controllo del codice sorgente locale sed -i ""senza backup, dovrebbe andare bene per la maggior parte del tempo (o appena git init && git add -A . && git commit -m 'backup'prima di eseguire sed in -imodalità).
cfeduke,

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

5
BSD sed richiede che non ci sia spazio dopo la bandiera -i. Quindi, -i''è valido, ma -i ''non lo è.
Todd A. Jacobs,

3
Argh! BSD sed sta ignorando il carattere '\ n' e stampa invece 'n'! Sto per sostituire BSD sed con GNU sed sul mio mac!
nterry

20

Ho un problema simile con MacOS

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

non funziona, ma

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

funziona bene.


Questo è ora il contrario. sed -i '' <file>funziona ma sed -i'' <file>non funziona più
Zohaib Amanzai,


4

Puoi usare -i''( --in-place) per sedcome già suggerito. Vedi: L' -iargomento sul posto , comunque nota che l' -iopzione è estensioni di FreeBSD non standard e potrebbe non essere disponibile su altri sistemi operativi. In secondo luogo sedè un S tream ED itor, non un editor di file .


Il modo alternativo è usare la sostituzione integrata in modalità Vim Ex, come:

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

e per più file:

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

Per modificare tutti i file in modo ricorsivo puoi usare **/*.*se la shell lo supporta (abilita per shopt -s globstar).


Un altro modo è quello di utilizzare gawke la sua nuova estensione "inplace" come:

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

4

Questo crea file di backup. Ad esempio, sed -i -e 's/hello/hello world/' testfileper me, crea un file di backup, testfile-e, nella stessa directory.


Lo stesso qui con Mac OS Catalina. Passando sia -i che -e separatamente (NON -ie insieme!) Si crea un file di backup con '-e' aggiunto.
Daniel Kesner,

1

Puoi usare:

sed -i -e 's/<string-to-find>/<string-to-replace>/' <your-file-path>

Esempio:

sed -i -e 's/Hello/Bye/' file.txt

Funziona perfettamente su Mac .


2
Questo crea un file di backup per me in Mac OS Catalina con '-e' aggiunto.
Daniel Kesner,

Questo è sbagliato per macOS. Dai un'occhiata alla pagina "man sed" lì. -irichiede un argomento per macOS. Poiché non ne specifichi uno, lo utilizza -e, il che si traduce in un secondo file con l' -eaggiunta. -enon esiste in macOS, lo è -E. Quindi il comando corretto per macOS èsed -i '' -E 's/Hello/Bye/' file.txt
Marc J. Schmidt l'
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.