444 votes

sed édite le fichier en place

J'essaie de savoir s'il est possible de modifier un fichier à l'aide d'une seule commande sed sans transmettre manuellement le contenu modifié dans un nouveau fichier, puis de renommer le nouveau fichier avec le nom de fichier d'origine. J'ai essayé l'option -i mais mon système Solaris a indiqué que -i était une option illégale. Y a-t-il un moyen différent?

Merci

726voto

choroba Points 56333

L'option -i diffuse le contenu modifié dans un nouveau fichier, puis le renomme en coulisse, quoi qu'il en soit.

Exemple: sed -i "s/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g" <file>

85voto

Steve Points 18420

Sur un système où sed n'a pas la capacité de modifier des fichiers sur place, je pense que la meilleure solution serait d'utiliser perl :

 perl -pi -e 's/foo/bar/g' file.txt
 

Bien que cela crée un fichier temporaire, il remplace l'original car un suffixe / extension vide a été fourni.

33voto

minhas23 Points 365

Ce qui suit fonctionne bien sur mon mac

 sed -i.bak 's/foo/bar/g' sample
 

Nous remplaçons foo par bar dans le fichier exemple. La sauvegarde du fichier original sera sauvegardée dans sample.bak

Pour éditer en ligne sans sauvegarde, utilisez la commande suivante

 sed -i'' 's/foo/bar/g' sample
 

20voto

Dwight Spencer Points 188

Une chose à noter, sed ne peut pas écrire des fichiers sur son propre que le seul but de la sed est d'agir en tant que rédacteur sur le "flux" (c'est à dire les pipelines de stdin, stdout, stderr, et d'autres >&n tampons, des sockets et des autres). Avec cela à l'esprit, vous pouvez utiliser une autre commande tee d'écrire la sortie dans le fichier. Une autre option est de créer un patch à partir de la tuyauterie, le contenu en diff.

Tee méthode

sed '/regex/' <file> | tee <file>

Patch méthode

sed '/regex/' <file> | diff -p <file> /dev/stdin | patch

Mise à JOUR:

Il est également à noter que le patch va obtenir le fichier à modifier de la ligne 1 de la diff de sortie:

Patch n'a pas besoin de savoir quels sont les fichiers à l'accès comme cela se trouve dans la première ligne de la sortie de diff:

$ echo foobar | tee fubar

$ sed 's/oo/u/' fubar | diff -p fubar /dev/stdin
*** fubar   2014-03-15 18:06:09.000000000 -0500
--- /dev/stdin  2014-03-15 18:06:41.000000000 -0500
***************
*** 1 ****
! foobar
--- 1 ----
! fubar

$ sed 's/oo/u/' fubar | diff -p fubar /dev/stdin | patch
patching file fubar

17voto

William Pursell Points 56211

Il n'est pas possible de faire ce que vous voulez avec sed. Même les versions d' sed qui prennent en charge l' -i option pour l'édition d'un fichier au lieu de faire exactement ce que vous avez explicitement déclaré que vous ne voulez pas: ils écrivent dans un fichier temporaire, puis renommez le fichier. Mais peut-être vous pouvez simplement utiliser ed. Par exemple, pour modifier toutes les occurrences de foo de bar le fichier file.txt, vous pouvez le faire:

echo ',s/foo/bar/g; w' | tr \; '\012' | ed -s file.txt

La syntaxe est similaire à l' sed, mais certainement pas exactement la même.

Mais peut-être que vous devriez vous demander pourquoi vous ne voulez pas utiliser un renommé le fichier temporaire. Même si vous n'avez pas de -i soutenant sed, vous pouvez facilement écrire un script pour faire le travail pour vous. Au lieu de sed -i 's/foo/bar/g' file, vous pourriez faire l' inline file sed 's/foo/bar/g'. Un tel script est facile à écrire. Par exemple:

#!/bin/sh -e
IN=$1
shift
trap 'rm -f $tmp' 0
tmp=$( mktemp )
<$IN "$@" >$tmp && cat $tmp > $IN  # preserve hard links

devrait être suffisant pour la plupart des utilisations.

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