sed avec expression multiple pour argumentation sur place

24

J'essaie de remplacer plusieurs mots dans le fichier en utilisant sed -i #expression1 #expression2

fichier

Something  123 item1
Something  456 item2
Something  768 item3
Something  353 item4

Sortie (souhaitée)

anything  123 stuff1
anything  456 stuff2
anything  768 stuff3
anything  353 stuff4

Essais

Je peux obtenir la sortie suivante en l'utilisant sed -i2 fois.

 sed -i 's/Some/any/g' file
 sed -i 's/item/stuff/g' file

Puis-je avoir un moyen possible de faire cela comme une commande unique sur place comme

sed -i 's/Some/any/g' -i 's/item/stuff/g' file

Lorsque j'ai essayé le code ci-dessus, il prend s/item/stuff/gun fichier et j'essaie de travailler dessus.

JigarGandhi
la source
Si vos fichiers sont similaires à l'exemple ci-dessus (c'est-à-dire qu'ils suivent le même modèle) vous pouvez le faire avec une seule substitution:sed - i 's/Some\(.*\)item/any\1stuff/' file
don_crissti

Réponses:

26

Selon la version de sedvotre système, vous pourrez peut-être le faire

sed -i 's/Some/any/; s/item/stuff/' file

Vous n'avez pas besoin gde la dernière barre oblique dans les commande ici, car vous ne faites qu'un seul remplacement par ligne.

Alternativement:

sed -i -e 's/Some/any/' -e 's/item/stuff/' file

L' -ioption indique sedde modifier les fichiers sur place; s'il y a des personnages immédiatement après l' -ialors sedfait une sauvegarde du fichier d' origine et utilise ces caractères comme l'extension du fichier de sauvegarde. Par exemple,

sed -i.bak 's/Some/any/; s/item/stuff/' file

ou

sed -i'.bak' 's/Some/any/; s/item/stuff/' file

va modifier file, en enregistrant l'original dans file.bak.

Bien sûr, sur un système Unix (ou de type Unix), nous utilisons normalement '~' plutôt que '.bak', donc

sed -i~ 's/Some/any/;s/item/stuff/' file
PM 2Ring
la source
2
Notez que vous décrivez la variante GNU. La variante BSD (comme dans FreeBSD ou OS / X) nécessite un argument pour -i. Alors sed -i '' 's/a/b/;s/c/d/' fileou sed -i .back 's/a/b/;s/c/d/'ou sed -i.back 's/a/b/;s/c/d/'là. Les autres sedimplémentations ne prennent généralement pas en charge -i.
Stéphane Chazelas
Merci @ StéphaneChazelas d'avoir clarifié cela. Et je suppose que j'aurais dû être plus explicite en disant que dans GNU sed, il ne peut pas y avoir d'espace entre le -iet l'extension.
2
sed -i 's/$username = "root"/$username = "newuser"/; s/$password = "password"/$password = "passwd"/; s/$dbname="handicraftstore"/$dbname="handicraft"' Web/database.phprésultats sed: -e expression #1, char 141: unterminated «commande»
alhelal
@alhelal Désolé, les commentaires ne sont pas le bon endroit pour poser des questions. Mais de toute façon, votre dernière scommande manque sa finale /.
PM 2Ring
@ PM2Ring car je n'ai pas remarqué que je pensais que c'était lié à votre solution. Mais merci.
alhelal
10

Vous pouvez chaîner des expressions sed avec ";"

%sed -i 's/Some/any/g;s/item/stuff/g' file1
%cat file1
anything  123 stuff1
anything  456 stuff2
anything  768 stuff3
anything  353 stuff4
Ian McGowan
la source
5

Expression multiple utilisant plusieurs -eoptions:

sed -i.bk -e 's/Some/any/g' -e 's/item/stuff/g' file

ou vous pouvez en utiliser un seul:

sed -i.bk -e 's/Some/any/g;s/item/stuff/g' file

Vous devez donner une extension pour le fichier de sauvegarde, car lorsqu'une implémentation de sed, comme OSX sed ne fonctionne pas avec une extension vide (vous devez utiliser sed -i ''pour remplacer les fichiers d'origine).

cuonglm
la source
1

Vous pouvez utiliser Vim en mode Ex:

ex -sc '%s/Some/any/|%s/item/stuff/|x' file
  1. % sélectionner toutes les lignes

  2. s remplacer

  3. x sauver et fermer

Steven Penny
la source