634 votes

Rechercher et remplacer dans un fichier et écraser le fichier ne fonctionne pas, cela vide le fichier.

J'aimerais exécuter une recherche et un remplacement sur un fichier HTML par le biais de la ligne de commande.

Ma commande ressemble à quelque chose comme ceci :

sed -e s/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g index.html > index.html

Lorsque je l'exécute et que je regarde le fichier par la suite, il est vide. Il a supprimé le contenu de mon fichier.

Quand j'exécute ceci après avoir restauré le fichier à nouveau :

sed -e s/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g index.html

El stdout est le contenu du fichier, et la recherche et le remplacement ont été exécutés.

Pourquoi cela se produit-il ?

14 votes

Alternative à Perl : perl -pi -w -e 's/STRING_TO_REPLACE/REPLACE_WITH/g;' index.html

0 votes

Beaucoup de choses liées sed pour trouver une chaîne de caractères et remplacer la ligne entière : stackoverflow.com/questions/11245144/

978voto

codaddict Points 154968

Lorsque le coquille voit > index.html dans la ligne de commande, il ouvre le fichier index.html para écrire en effaçant tout son contenu précédent.

Pour résoudre ce problème, vous devez passer l'option -i option pour sed pour effectuer les changements en ligne et créer une sauvegarde du fichier original avant d'effectuer les changements sur place :

sed -i.bak s/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g index.html

Sans le .bak, la commande échouera sur certaines plateformes, comme Mac OSX.

24 votes

En disant truncates the file au lieu de opens the file le rend probablement plus clair.

13 votes

Au moins sur mon Mac, la première suggestion ne fonctionne pas... si vous faites un remplacement in-place sur un fichier, vous devez spécifier une extension. Vous pouvez, au moins, passer une extension de longueur zéro : sed -i '' s/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g index.html

5 votes

Pour les variables sed -i.bak 's/'$search'/'$replace'/g' index.html

220voto

Norman Gray Points 4337

Un modèle alternatif, utile, est :

sed -e 'script script' index.html > index.html.tmp && mv index.html.tmp index.html

Cela a à peu près le même effet, sans utiliser la fonction -i et signifie également que, si le script sed script échoue pour une raison quelconque, le fichier d'entrée n'est pas endommagé. De plus, si l'édition est réussie, il n'y a pas de fichier de sauvegarde qui traîne. Ce genre d'idiome peut être utile dans les Makefiles.

Un grand nombre de seds ont le -i mais pas tous ; le sed de posix est l'un de ceux qui ne le font pas. Si vous recherchez la portabilité, il est donc préférable de l'éviter.

10 votes

+1 pour l'absence de fichier de sauvegarde et pour ne pas endommager le fichier d'entrée si l'édition échoue. Fonctionne parfaitement sur Mac.

1 votes

Cela a parfaitement fonctionné pour moi. Merci ! (sur un Mac)

1 votes

Cela a parfaitement fonctionné pour moi, alors que sur Ubuntu Server 14.04 sed -i continuait à mettre le fichier à zéro.

98voto

Rich Apodaca Points 7327
sed -i 's/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g' index.html

Cette opération effectue une substitution globale en place sur le fichier index.html. Le fait de citer la chaîne de caractères évite les problèmes d'espaces dans la requête et le remplacement.

60voto

Kevin Points 10204

Utiliser l'option -i de sed, par exemple

sed -i bak -e s/STRING_TO_REPLACE/REPLACE_WITH/g index.html

0 votes

Qu'est-ce que cela signifie ? sed : -i ne peut pas être utilisé avec stdin

2 votes

N'oubliez pas d'entourer votre motif de guillemets s'il contient des espaces. 's/STRING_TO_REPLACE/REPLACE_WITH/g'

0 votes

@sheetal : -i effectue une modification en cours de route de fichiers Il n'y a donc aucun sens à le combiner avec stdin l'entrée.

18voto

Stenemo Points 104

Pour modifier plusieurs fichiers (et sauvegarder une sauvegarde de chacun d'eux sous le format *.bak) :

perl -p -i -e "s/\|/x/g" *  

prendra tous les fichiers du répertoire et remplacera | con x cela s'appelle un "Perl pie" (facile comme une tarte)

1 votes

C'est bien de voir que quelqu'un est prêt à examiner l'énoncé du problème, et pas seulement les étiquettes. L'OP n'a pas spécifié sed comme une exigence, seulement utilisé comme un outil déjà essayé.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X