plume
Voici une petite astuce bien pratique qui permet de changer une chaîne de caractères par une autre, contenue dans un fichier texte. Tout ceci se réalise en une seule ligne de commande, grâce à sed.

Voici un exemple d'utilisation :

sed -i -e "s/chaines1/chaine2/g" fichier

A noter que si la chaîne contient des caractères spéciaux, on devra les échapper avec '\'. Voici un exemple oû l'on remplace "/home" par "/tmp" :

sed -i -e "s/\/home/\/tmp/g" fichier

Si on a besoin de remplacer une chaîne par une autre pour toute une liste de fichiers contenue dans un répertoire, on pourra utiliser ce petit script basé sur le même principe :

#!/bin/bash
for file in *.txt
do
  echo "Traitement de $file ..."
  sed -i -e "s/chaine1/chaine2/g" "$file"
done

Ce dernier va :
1. établir la liste de tous les fichiers dont l'extension est .txt
2. puis effectuer le remplacement

Edit : une autre méthode donnée en commentaire qui utilise la commande find et qui permet de traiter des sous-dossier en plus :

find . -name "*.txt" -type f -exec sed -i "s/chaine1/chaine2/g" {} \;


36 Commentaires pour "Remplacer un chaine de caractère avec la commande sed"

Flux des commentaires de cet article Ajouter un commentaire
  •  

    @Laurent Rineau : merci pour l'info, c'est vrai que dans le cas du script qui peut modifier énormément de fichiers, cela peut être très utile. Je modifie mes commandes.

    pti-seb , le 12 décembre 2007 à 18:41
  •  

    Si tu utilises GNU/sed, tu peux utiliser l'option -i pour te faciliter la vie. Ton premier exemple se transforme en :
    sed -i -e "s/chaines1/chaine2/g" fichier

    et ton deuxième exemple, le script bash, se transforme en :
    sed -i -e "s/chaine1/chaine2/g" *.txt

    Si tu mets un truc après l'option -i, sed crée des backups. Exemple :
    sed -i.bak -e "s/chaine1/chaine2/g" *.txt
    va modifier tous les *.txt et va créer des backups *.txt.bak.

    Laurent Rineau , le 12 décembre 2007 à 18:32
  •  

    Au-lieu de "for ...", find peut être plus élégant.

    find . -name "*.txt" [+ plein de conditions] -exec cp -p {} {}.orig \; -exec sed -i "s/tralala/trilili/g" {} \;

    Le premier "-exec" fait une copy.

    moi , le 12 décembre 2007 à 19:06
  •  

    @moi :
    1/ Ta notion « d'élégant » est très douteuse. :-) Moi je préfère largement utiliser les boucles for du shell que find. Notamment avec le shell Zsh le glob permet d'avoir n'importe quelle condition, comme find et même plus.
    2/ Tu n'as pas lu ce que j'ai écris : ta copie est inutile, avec une option "-i.orig" à sed.

    Laurent Rineau , le 12 décembre 2007 à 19:17
  •  

    A note r: Plutôt que protéger le caractère / car vous utilisez le caractère / comme séparateur, utilisez plutôt le caractère #

    Exemple :
    sed -e "s/\/home/\/tmp/g" fichier > fichier.tmp && mv -f fichier.tmp fichier

    Plus facile :
    sed -e "s#/home#/tmp#g" fichier > fichier.tmp && mv -f fichier.tmp fichier

    Ca peut sauver la vie dans des scripts ;)

    krusaf , le 12 décembre 2007 à 19:25
  •  

    @moi : c'est vrai que je n'avais pas pensé au find.

    Mais l'avantage du script est que l'on peux facilement rajouter d'autres opérations. Maintenant find à l'avantage de traiter les sous-repertoires de façon bien plus simple.

    @krusaf : c'est noté.

    pti-seb , le 12 décembre 2007 à 19:28
  •  

    C'est clair que pour le coup un for est largement plus clair que find. Find vaut le coup quand les fichiers à modifier sont plus difficiles à retrouver.

    Par contre, pense à utiliser les guillemets doubles pour les noms de fichiers ("$file") au cas où tu tombes sur des noms avec des espaces...

    liberforce , le 12 décembre 2007 à 19:41
  •  

    @liberforce : j'ai fait la modification du script afin d'ajouter les guillemets.

    pti-seb , le 12 décembre 2007 à 19:55
  •  

    J'avais écrit un billet sur le sujet: blog.nicolargo.com/2007/0...

    La méthode utilisait Perl:
    # find ./ -type f | xargs perl -pi -w -e 's/titi/tata/g'

    a+

    Nicolargo , le 12 décembre 2007 à 21:21
  •  

    Pour Nicolargo

    Préfères :
    $ find ... -print0 | xargs -0 ....
    Ainsi les noms de fichiers qui ont un retour chariot ne posent pas de problème.

    moi , le 12 décembre 2007 à 23:08
  •  

    Tiens au fait, j'avais fait un 'ti post sur les expressions régulières avec "sed" en exemple.
    Si ça t'intéresse : temet79.free.fr/index.php...

    (désolé pour le lien à rallonge)

    Temet , le 14 décembre 2007 à 11:35
  •  

    @Nicolargo, @moi, @Temet : merci pour les infos.

    pti-seb , le 14 décembre 2007 à 11:38
  •  

    Y a pas a dire, le bash c'est vraiment util :).

    scraly , le 18 décembre 2007 à 10:18
  •  

    Si l'on veut faire une modification dans plusieurs fichiers qui sont dans plusieurs répertoires,
    est ce qu'un "for file in */*.txt" peut fonctionner ?

    merci :)

    scraly , le 18 décembre 2007 à 11:45
  •  

    @scraly : en mettant */*.txt tu ne traitera que les fichier txt contenu dans des sous-répertoire. les fichiers dans le répertoire courant, tous ceux contenu dans des sous-sous-répertoire ne seront pas pris en compte.

    pti-seb , le 19 décembre 2007 à 17:25
  •  

    Bonjour,

    J'ai une petite question... Si quelqu'un peut m'aider ça serait cool :-)
    Je voudrai modifier des caractéres dans une chaine de caractére, sachant qu'elle est contenu dans une variable. Est-ce que "sed" peut le faire?

    Je vous pose mon problème... En fait j'ai un format de date qui est le suivant:
    date=2008Fev22 (22 Fevrier 2008). Et je voudrai remplacer le Fev par un 02. Peut-on avec sed, spécifier la variable "date" pour que la modification se fasse que sur la variable et non sur un fichier???

    Merci pour vos réponse

    Mus

    Muss , le 23 février 2009 à 14:57
  •  

    @Muss : essaye comme ceci :

    sed -e "s/date=2008Fev22/date=20080222/g" fichier

    pti-seb , le 23 février 2009 à 16:29
  •  

    ma variable date=`grep EMS /var/adm/syslog/syslog.log | awk '{print $1 $2 $3}'`

    echo $date
    ==> 2008Fev22

    je voudrai une commande qui puisse chnager le "Fev" en "02" juste en spécifiant la variable...
    Merci pour votre aide :-)

    Muss , le 23 février 2009 à 21:29
  •  

    J'ai essaye ce script. Mais ça ne me donne rien. Aucun fichier n'est modifie.

    #!/bin/sh
    echo enter file name with extension
    read NAME
    echo enter expression to replace
    read FIND
    REPLACE=""
    find . -name $NAME -type f | xargs sed -i -e 's/$FIND/$REPLACE/g'

    heyyo , le 30 novembre 2009 à 16:44
  •  

    Bonjour,

    je souhaiterai modifier une chaine de caractere dans plusieurs fichier mais mon problème est que ce remplacement de chaîne de caractère est different d'un fichier à un autre.

    J'ai pensé mettre trois colonne dans un fichier exel : la premiere contiendrait la liste des fichier à midifier la deuxième la chaine de caractère à remplacer et enfin la troisième la nouvelle chaine de caractère.

    quelqu'un aurait une petite idée?

    Merci :o)

    liza74 , le 31 août 2011 à 12:18
  •  

    @liza74 : Pour chaque fichier voulus tu fais ta modif en combinant sed a find :

    find . -name monfichier -type f --exec sed -i -e 's/$FIND/$REPLACE/g' {}

    KoHead , le 31 août 2011 à 15:13
  •  

    nickel merci ! tes collègues chez qui je suis tombé n'expliquaient pas comment échapper les car spéciaux.

    laloune , le 23 septembre 2011 à 13:56
  •  

    @Muss : La meilleur et simple facon de modifier la date en linux est la suivante:

    #date 022215302008

    avec: 02 representant le mois
    22 representant le jour
    1530 representant l'heure et les minutes
    2008 representant l'annee

    ecomputerclass , le 23 janvier 2012 à 02:38
  •  

    Bonjour svp quelqu'un pulse m'aider !!!
    je veux fair un script que je lui passe en parameter un nom et qu'il efface un # qui se trouve au début de cette ligne qui contient ce nom

    hamza , le 19 mars 2012 à 10:00
  •  

    @hamza : si tu espéres encore une réponse ou pour d'autres qui réinterrogeraient de savoir comment faire:

    echo "### tomy"| sed -e "s/^##* *//"

    Fonctionne quelque-soit le nombre de # et supprime les éventuels espaces devant le nom.

    tomylee , le 9 mai 2012 à 09:38
  •  

    merci bqq cv j'ai passé cette etape mtn je veux supprimer une chaine dans un fichier sans supprimer tous le contenue de fichier

    hamza , le 9 mai 2012 à 10:43
  •  

    echo "### début-chaîne-à-supprimer-fin le reste de mon fichier" > fichier.txt

    sed -i "s/début.*fin//" fichier.txt

    ou supprimer simplement le mot chaîne du fichier.txt:

    sed -i "s/chaîne//" fichier.txt

    tomylee , le 9 mai 2012 à 11:40
  •  

    non c pas je veux supprimer une chaine dans un fichier cfg
    la chaine est variable que je la passe en parametre dans un script shell sous php !!
    shell_exet("script.sh".$chaine);
    mon prob que le script ne connais jamais la chaine par contre si je fait un echo avan just shell-exec je vois ma chaine

    hamza , le 9 mai 2012 à 12:21
  •  

    script.sh:
    #!/bin/bash
    sed -i "s/$1//" fichier.cfg

    shell_exec('sh script.sh ' . $chaine)

    tomylee , le 9 mai 2012 à 13:49
  •  

    ouiii c bien exatement ca !! mon probleme que le script ne connais pas mon variable($chaine)!!
    j'ai vu au log (not found)!!!!je comprend pas pk

    hamza , le 9 mai 2012 à 14:17
  •  

    Bonjour,

    Dans mon cas, je veux remplacer crocher "[" par un blanc, voici ma syntaxe : sed s'/[//g' , mais ca me donne l'erreur suivante : sed: -e expression #1, char 6: unterminated `s' command.

    Merci

    redaamine , le 10 décembre 2013 à 15:37
  •  

    Bonjour,
    J'utilise un script dans ce genre :
    find . -name "*.php" -type f -exec sed -i "s/chaine1/chaine2/g" {} \;

    Le problème est que tous mes fichiers php voient leur date modifiée, même s'ils ne sont pas concernés par le remplacement, ce qui est problématique pour moi. Qui connaîtrait le moyen de ne modifier que les fichiers concernés par la substitution ?

    Christophe , le 9 juin 2014 à 14:29
  •  

    Bonjour je souhaite modifier le nom d'une série de fichiers à la fois
    exemple fichier:
    RH_A_142_2_timestamp.dat
    RH_B_142_2_timestamp.dat
    RH_C_142_2_timestamp.dat
    etc...
    je souhaite enlever le 142_2 de tous mes fichiers ?
    donc avoir :
    RH_A_timestamp.dat
    RH_B_timestamp.dat
    RH_C_timestamp.dat

    pourriez vous m'aider à trouver une expression simple ??
    merci

    knock , le 20 novembre 2017 à 16:58
  •  

    Bonjour knock ,

    sed -i 's/RH_A_142_2_timestamp.dat/RH_A_timestamp.dat/g'

    le meme pour b et c

    Cordialement;

    Hazem Tounsi , le 4 décembre 2019 à 16:30
  •  

    Salut,

    Je voudrais ajouter une ligne en fin de fichier à une série de pages web nommées mesfichiers.md.html (c'est du markdown mélioré), j'ai utilisé la commande suivante:

    find . -name "*.md.html" -type f -exec sed -e '$a\la ligne à ajouter ' {} \;

    Le terminal affiche bien la modif dans mes fichiers mais elle n'est pas réalisée dans mes fichiers !!!

    Si vous pouvez m'aider

    Cordialement

    jean , le 15 juin 2020 à 15:12
  •  

    Bonjour,

    Moi je voudrais changer un fichier csv de mon stock pour le rendre compatible avec ma base de mon CMS.
    Le problème je bloque sur cela :
    sed -i -e "s/\749/\MONTRES HOMME/g" $OUT

    Il me fait une erreur quand je recherche des chiffres?

    sed: 1: "s/\749/\MONTRES HOMME/g": RE error: invalid backreference number

    Alors que quand c'est des lettres pas de problème.
    J'ai essayé d'entourer avec des ' " () rien a faire, une idée?
    Google m'a pas aidé sur le coup là :(

    MErci

    BAF , le 24 juin 2020 à 16:57

actualité android apache apple astuce astuces bash bilboblog blog boot chrome clavier commande commandes conky date debian Desktop développement elementary exploit faille fedora firefox flash gimp gnome google graphique Graphisme hack hacking Hardware humour intel internet iphone jailbreak Jeux Kde kernel libre Linux log logiciels Logiciels Libres lucid lynx maemo mail maquette metasploit microsoft mobile mockup monitoring mozilla multi-touch musique mysql n900 nautilus nokia noyau openoffice open source password photos php Planet publicité redhat red hat rpm réseau screenshot script serveur serveurs shell sql ssh statistiques sysadmin system Sécurité thème tux-planet tv twitter ubuntu unity vidéo vidéos vlc voyage wallpaper windows wordpress yum