Modifications sur place avec sed sur OS X


142

Je voudrais éditer un fichier avec sed sur OS X. J'utilise la commande suivante:

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

La sortie est envoyée au terminal. file.txt n'est pas modifié. Les modifications sont enregistrées dans file2.txt avec cette commande:

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

Cependant, je ne veux pas d'autre fichier. Je veux juste éditer file1.txt . Comment puis-je faire ceci?

J'ai essayé l'indicateur -i. Cela entraîne l'erreur suivante:

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

2
Quelle est la commande exacte que vous utilisez lorsque vous essayez le -idrapeau?
eldarerathis

Réponses:


282

Vous pouvez utiliser -icorrectement l' indicateur en lui fournissant un suffixe à ajouter au fichier sauvegardé. Prolonger votre exemple:

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

Vous donnera deux fichiers: un avec le nom file1.txtqui contient la substitution et un avec le nom file1.txt.buqui a le contenu original.

Légèrement dangereux

Si vous souhaitez écraser de manière destructive le fichier d'origine, utilisez quelque chose comme:

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

En raison de la façon dont la ligne est analysée, un espace est requis entre l'indicateur d'option et son argument car l'argument est de longueur nulle.

Hormis le fait de détruire votre original, je ne suis pas au courant des autres dangers de tromper sed de cette façon. Il convient de noter, cependant, que si cet appel de sedfait partie d'un script, The Unix Way ™ serait (à mon humble avis) d'utiliser de manière sednon destructive, de tester qu'il est sorti proprement et de supprimer ensuite le fichier superflu.


Vous avez raison, j'omettais l'extension après le drapeau -i. Est-il -i''dangereux pour une raison autre que de potentiellement gâcher le fichier d'origine (et ne pas avoir de sauvegarde)?
DimancheLundi

Selon la sedpage de manuel, si vous manquez d'espace disque sur le périphérique, vous pouvez corrompre un fichier à mi-chemin et obtenir un résultat de sortie incorrect. Si vous travaillez sous contrôle de source local sed -i ""sans sauvegardes, cela devrait aller la plupart du temps (ou juste git init && git add -A . && git commit -m 'backup'avant d'exécuter sed en -imode).
cfeduke

2
J'ai trouvé la partie légèrement dangereuse particulièrement utile. +1
Andre

5
BSD sed exige qu'il n'y ait pas d'espace après l'indicateur -i. Donc, -i''est valide, mais -i ''ne l'est pas.
Todd A. Jacobs

3
Argh! BSD sed ignore le caractère '\ n' et imprime 'n' à la place! Je vais juste remplacer BSD sed par GNU sed sur mon mac!
nterry

20

J'ai un problème similaire avec MacOS

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

ne fonctionne pas, mais

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

fonctionne bien.


C'est maintenant l'inverse. sed -i '' <file>fonctionne mais sed -i'' <file>ne fonctionne plus
Zohaib Amanzai


4

Vous pouvez utiliser -i''( --in-place) pour sedcomme déjà suggéré. Voir: L' -iargument sur place , cependant, notez que l' -ioption est des extensions FreeBSD non standard et peut ne pas être disponible sur d'autres systèmes d'exploitation. En second lieu sedest un S tream ED Itor, pas un éditeur de fichiers .


Une autre méthode consiste à utiliser la substitution intégrée en mode Vim Ex, comme:

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

et pour plusieurs fichiers:

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

Pour éditer tous les fichiers de manière récursive, vous pouvez utiliser **/*.*si le shell le prend en charge (activer par shopt -s globstar).


Une autre façon est d'utiliser gawket sa nouvelle extension "inplace" telle que:

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

4

Cela crée des fichiers de sauvegarde. Par exemple, sed -i -e 's/hello/hello world/' testfilepour moi, crée un fichier de sauvegarde, testfile-e, dans le même répertoire.


Même chose ici avec Mac OS Catalina. Passer à la fois -i et -e séparément (PAS -ie ensemble!) Crée un fichier de sauvegarde avec '-e' ajouté.
Daniel Kesner le

1

Vous pouvez utiliser:

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

Exemple:

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

Cela fonctionne parfaitement sous Mac .


2
Cela crée un fichier de sauvegarde pour moi dans Mac OS Catalina avec '-e' ajouté.
Daniel Kesner le

C'est faux pour macOS. Veuillez consulter la page "man sed" ici. -inécessite un argument pour macOS. Comme vous n'en spécifiez pas, il l'utilise -e, ce qui entraîne un deuxième fichier avec -e. -en'existe pas dans macOS, c'est le cas -E. La commande correcte pour macOS estsed -i '' -E 's/Hello/Bye/' file.txt
Marc
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.