La commande sed
sur plusieurs fichiers
C'est quoi sed
?
sed
est un éditeur de flux.
Concrètement, il permet de transformer
du texte venant d'un flux
(un fichier ou un tube de communication inter-processus).
Il est efficace et s'utilise en ligne de commande.
C'est un des programmes spécifiés dans POSIX
(il est donc disponible de base sur GNU/Linux et les BSD).
Remplacer dans un fichier avec sed
Pour une raison ou une autre,
vous devez remplacer une chaine de caractères par une autre
dans un fichier contenant du texte brut,
cela tombe bien, sed
c'est le faire.
Par exemple, pour remplacer "ancienne" par "nouvelle"
dans un premier fichier et
mettre le résultat dans un second fichier,
la commande suivante fait le travail :
sed -e 's/ancienne/nouvelle/g' fichier1.txt > fichier2.txt
.
Mais vous voulez peut-être
remplacer directement dans le fichier,
sed
peut encore une fois
être un précieux compagnon
(grâce à son option --in-place
qui est -i
en version courte) :
sed -i 's$http://vieux.fr$https://nouveau.fr$g' fichier.txt
.
Au besoin, il est capable de
faire une sauvegarde de l'ancien fichier,
il suffit pour cela de coller un suffixe à l'option,
par exemple avec le suffixe ".bak"
(pour backup) :
sed -i.bak 's$vieux$nouveau$g' doc.txt
.
Plusieurs fichiers d'un coup
Script shell
On peut se faire un petit script shell
pour appeler sed
sur plusieurs fichiers.
Ce n'est pas bien compliqué, mais ce n'est pas très pratique.
for filepath in *
do
if test -f "$filepath"
then
sed -i 's/ancien/nouveau/g' "$filepath"
fi
done
Combiner sed
et find
Qu'est ce que find
?
find
a pour fonction de rechercher
des fichiers sans s'appuyer sur le contenu.
Le plus courant est de le faire rechercher en fonction du nom
(potentiellement via une expression régulière,
aussi appelée regex).
Cependant il gère d'autres propriétés pour filtrer sa recherche
(comme la date de modification et les permissions).
Il peut appliquer des opérations sur les fichiers :
les afficher (dans divers formats), les supprimer,
ou exécuter n'importe quelle commande dessus.
C'est une commande POSIX
(qui est donc très propablement pré-installé
sur votre distribution GNU/Linux ou BSD préférée).
Comment utiliser find
?
-
Lister tous les fichiers (y compris les dossiers)
du dossier courant
(
pwd
pour savoir êtes) :find .
-
Lister tous les fichiers (sans les dossiers)
du dossier courant :
find . -type f
-
Lister tous les fichiers HTML du dossier courant :
find . -name '*.html'
-
Lister tous les fichiers HTML du dossier courant
sans tenir compte de la casse
(c'est-à-dire avec ou sans les majuscules) :
find . -iname '*.html'
Pour en savoir plus, RTFM
(Read The Fucking Manual,
ce qui en français donne : lisez le putain de manuel).
Pour cela, vous pouvez utilisez
(dans un terminal textuelle)
man find
ou
info find
.
Si vous voulez passer votre vie dans Emacs, il y a
M-x man RET find
et
M-x info-display-manual RET find
(avec "M" étant la touche méta
qui est souvent la touche
find
tout seul
find
a une option -exec
.
Celle-ci permet d'exécuter une commande
sur les fichiers que find
a trouvé.
Un caractère point-virgule sert à
lui indiquer la fin de commande
(il faut penser à l'échapper
ou le mettre entre guillemets
sinon votre shell va l'interpréter)
et "{}" sera remplacer par le nom du fichier.
Ainsi, vous pouvez
supprimer tous les fichiers du dossier courant avec
find . -type f -exec rm -i {} \;
(vous me direz que rm
se serait très bien
débrouillé tout seul mais je n'étais pas inspiré
pour trouver un exemple simple).
Plutôt qu'exécuter la commande à chaque fichier,
vous préfériez l'exécuter qu'une fois pour tous :
il suffit de remplacer le point-virgule par le signe plus
(ce qui, en reprennant l'exemple précédent, donne
find . -type f -exec rm -i {} +
).
Utilisons maintenant notre ami sed
(quoi ?
vous doutez que l'on puisse être ami
avec un programme informatique ?).
Vous devriez deviner comme combiner
find
et sed
.
Mais au cas où ce ne serait pas le cas,
prenons un exemple.
Votre super site web personnel
était accessible uniquement en HTTP,
mais il y a maintenant du HTTPS
pour la vie privée de vos visiteurs et visiteuses.
Mais vous avez mis un lien vers votre site web personnel
dans le pied de page de
votre site web sur le logiciel libre ou Emacs
(qui est tellement mieux que vim
…).
Diantre, tant de fichiers HTML à modifier,
heureusement sed
et find
sont là :
find . -type f -iname '*.html' -exec sed -i 's$http://monsiteweb.fr/$https://monsiteweb.fr/$g' {} \;
.
Alors, oui, l'exemple est encore pourri,
car vous utilisez un générateur de site web statique
ou un programme générateur de site web
(expression fourre-tout pour inclure
tout ce qui n'est pas statique,
des bêtes include
en PHP
à une usine à gaz comme WordPress),
mais il a le mérite d'exister et
d'avoir permis d'inclure un petit troll au passage.
find
avec xargs
xargs
est une commande POSIX
qui permet de construire et exécuter des commandes
en utilisant l'entrée standard
(stdin
en langage C et
std::cin
en C++).
Si on voulait faire la même chose que dans l'exemple avec
find
et son option -exec
,
on ferait la commande suivante :
find . -type f -iname '*.html' | xargs sed -i 's$http://monsiteweb.fr/$https://monsiteweb.fr/$g'
.