Chercher/remplacer en bash

Qui a dit que la ligne de commande était morte sous Linux ? Voilà un exemple dés plus simple où un petit script vaut mieux qu'une interface graphique...

Mon problème était le suivant : j'ai modifié une partie de la syntaxe wiki que j'utilise pour mettre en forme les textes du site, notamment pour l'insertion de la balise strong. Dés lors, comment remplacer rapidement et simplement dans tous mes fichiers (articles et brèves) la suite de caractères « __ » (syntaxe wiki originale) par « ** » (nouvelle syntaxe) ?

Sous Windows, j'aurai sans doute créé un script Autoit. Sous Linux, il n'est pas nécessaire d'installer un programme particulier : les outils fournit par défaut sur toute distribution suffisent. Je n'avais donc qu'à écrire un script de quelques lignes dans un éditeur de texte :

#! /bin/bash
# nom : s-r-xml.sh
# date : 20/12/2005
# par : Rui Nibau (RNB)
# ----------------------------------------------------
# input : rechercher|remplacer
gui=`zenity --title "Chercher|Remplacer" --entry --text "Entrer le texte : chercher|remplacer" `
# si la recherche n'est pas validée
if [[ "$?" != 0 ]]; then
    zenity --title "Chercher|Remplacer" --info --text "Recherche abandonnée"
    exit
fi
# spliter l'output
search=`echo ${gui} | cut -f1 -d \|`
replace=`echo ${gui} | cut -f2 -d \|`
# pour tout les fichiers .xml du répertoire courant
for file in *.xml
    do
    cp $file $file.bak &&
    sed "s|${search}|${replace}|g" $file.bak >$file
done
# remplacement effectué
zenity --title "Chercher | Remplacer" --info --text "Remplacement effectué"

Ce script travaille dans le répertoire courant (celui dans lequel vous vous trouvez) et effectue les opérations suivantes :

  • Affichage d'une petite fenêtre graphique avec un champ dans lequel il faut taper « expression à chercher|expression pour remplacer ».
  • Pour tous les fichiers .xml du répertoire courant, faire une copie de sauvegarde (.bak)
  • Remplacer l'expression à rechercher dans les fichiers .xml. Pour travailler sur d'autres formats de fichiers, il suffit de changer l'extension recherchée dans la boucle (*.txt par exemple).

Une fois assuré que rien de facheux n'est arrivé, il ne reste plus qu'à supprimer tous les fichiers de sauvegarde .bak dans le répertoire courant :

rm *.bak

Enfin, si je place ce script dans le répertoire .gnome2/nautilus-scripts/, il apparaîtra dans le menu Fichier du navigateur de fichiers de Gnome. Il suffit alors de se rendre dans le répertoire où effectué la recherche, de faire un clic droit puis scripts->s-r-xml.sh et le script est lancé dans le dit répertoire.

Attention : comme toujours, si vous ne comprenez pas les lignes de code ci-dessus, n'essayez pas le script :-). Malgré sa simplicité, c'est un script puissant qui manipule le contenu de fichiers et qui peut donc supprimer certaines de vos données s'il est mal utilisé.

En tant qu'ex-windowsien, je suis bien-sur « formaté » à l'utilisation intensive des interfaces graphiques. Mais la ligne de commande, ou l'écriture de scripts bash, reste un outil indispensable et fort pratique qui n'est pas uniquement destiné aux professionnels de la profession.

Tant que les développeurs de distributions Linux garderont cette dualité au coeur de leurs priorités (environnement graphique convivial type Gnome ou Kde et console et ligne de commande), y compris pour des produits destinés au grand public, Linux gardera l'avantage. Que toutes les pratiques quotidiennes puissent se faire sans toucher à la console, oui. Mais que l'on ne nous prive pas de cette possibilité simplement parce que la ligne de commande fait peur. Car il ne faut pas perdre d'un côté ce que l'on donne de l'autre. Et les peurs, ca se surmonte.

Note (09 janvier 2006) : Fun Sun me fait remarqué à juste titre que la description de ce script pourrait porter à confusion. Je le présente en effet comme un exemple de la puissance du language en ligne de commande bash. Or, il fait aussi appel à zenity, un programme qui permet de construire de petites fenêtres graphique à partir de GTK+, un programme indépendant du bash et qui apparemment n'est pas installé par défaut sur toute les distributions linux.

D'un autre côté, signalons aussi que le script fonctionne très bien (et sans doute mieux) sans zenity, en ligne de commande pure :

#! /bin/bash
for file in *.xml
    do
    cp $file $file.bak &&
    sed "s|$1|$2|g" $file.bak > $file
done

Pour le lancer dans le répertoire courant, il suffit de taper dans une console :

chemin_du_script/s-r-xml.sh CHERCHE REMPLACE

CHERCHE est le mot à recherché et REMPLACE le mot qui le remplacera.