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.