HOWTO · Bash

Remplacement de chaîne dans Bash

Ce didacticiel montre comment remplacer une sous-chaîne par une autre chaîne dans bash.

Sur cette page

Choisissez une méthode de remplacement selon l’endroit où se trouve le texte : l’expansion de paramètres de Bash calcule une valeur de remplacement à partir d’une variable du shell courant sans modifier cette variable, sed transforme les lignes d’un flux, et awk convient lorsque le remplacement s’inscrit dans le traitement d’enregistrements. Chaque exemple est autonome ; les exemples qui traitent des fichiers créent leur propre fichier d’entrée temporaire.

Choisir une méthode de remplacement

Pour une valeur déjà stockée dans une variable Bash, l’expansion de paramètres évite de lancer un autre processus. Utilisez sed pour effectuer des substitutions simples sur les lignes d’entrée, notamment lorsque celles-ci proviennent d’un tube. Choisissez awk lorsque le même passage doit aussi traiter des champs, des enregistrements ou des conditions. Une commande qui lit un fichier et redirige le résultat vers un autre fichier préserve la source ; une option de modification sur place change la source et demande davantage de précautions.

Les exemples utilisent le texte littéral old comme motif de recherche et new comme remplacement. Dans l’expansion de paramètres de Bash, ces formes ne traitent pas automatiquement le texte recherché comme une expression régulière ; sed et awk ont, eux, leur propre syntaxe de motifs. Si l’entrée ou le remplacement contient un délimiteur utilisé par l’outil, choisissez un délimiteur adapté et échappez les caractères nécessaires.

Remplacer la première occurrence ou toutes les occurrences avec l’expansion de paramètres de Bash

L’expansion de paramètres de Bash remplace la première occurrence correspondant au motif avec ${value/pattern/replacement}. Ajoutez une deuxième barre oblique pour remplacer toutes les occurrences : ${value//pattern/replacement}. Dans ces exemples, value est définie localement : la variable d’origine reste donc inchangée et le résultat est stocké dans updated.

Exécutez cet exemple :

Le code et les libellés ou sorties affichés dans cette section restent en anglais.

value='red old blue old'
updated="${value/old/new}"
printf '%s\n' "$updated"
red new blue old

Pour remplacer toutes les occurrences dans la même valeur :

value='red old blue old'
updated="${value//old/new}"
printf '%s\n' "$updated"
red new blue new

Le motif suit la syntaxe des motifs de Bash : des caractères comme * ont donc une signification particulière. Si les motifs proviennent de variables ou de l’entrée de l’utilisateur, protégez-les ou traitez-les avec précaution. L’expansion de paramètres agit sur une seule valeur du shell ; elle ne modifie pas directement un fichier.

Faire correspondre un motif à la fin d’une chaîne

La forme avec un signe pour cent, ${value%pattern}, supprime le suffixe le plus court correspondant à pattern ; ${value%%pattern} supprime le suffixe correspondant le plus long. Elle ne signifie pas, en général, « trouver la dernière occurrence » à l’intérieur d’une chaîne. Pour remplacer un suffixe connu, vérifiez ou transformez explicitement cette terminaison. Par exemple, le remplacement d’un suffixe .txt peut s’exprimer avec un motif qui correspond à cette terminaison :

Le code et les libellés ou sorties affichés dans cette section restent en anglais.

filename='report.txt'
updated="${filename%.txt}.md"
printf '%s\n' "$updated"
report.md

Cette opération concerne uniquement un suffixe correspondant au motif. Une séquence .txt située plus tôt dans le nom n’est pas sélectionnée par ce motif de suppression de suffixe. Si les noms peuvent avoir d’autres terminaisons, vérifiez le suffixe attendu avant d’appliquer la transformation afin de traiter délibérément les noms qui ne correspondent pas.

Remplacer du texte dans des flux et des fichiers avec sed

La forme de substitution de sed, s/pattern/replacement/, modifie la première occurrence sur chaque ligne d’entrée. Ajoutez g après le dernier délimiteur pour remplacer toutes les occurrences de chaque ligne. Cette commande autonome lit un fichier et écrit le texte transformé sur la sortie standard :

Le code et les libellés ou sorties affichés dans cette section restent en anglais.

input=$(mktemp)
trap 'rm -f "$input"' EXIT
printf '%s\n' 'old road, old bridge' > "$input"
sed 's/old/new/g' "$input"
new road, new bridge

Pour enregistrer le résultat sans modifier la source, redirigez la sortie vers un autre fichier, par exemple output.txt. Évitez d’utiliser le même chemin pour l’entrée et la sortie redirigée : le shell ouvre la destination avant que sed ne lise le fichier, ce qui peut tronquer la source. L’option -i modifie directement le fichier, et la syntaxe de sauvegarde varie selon les implémentations de sed. Vérifiez d’abord la commande sur une copie ou utilisez un fichier de sortie séparé ; créez une sauvegarde si une modification sur place est nécessaire.

Dans une expression sed, / est le délimiteur habituel. Si le motif de recherche ou le remplacement en contient, choisissez un autre délimiteur, comme |, et échappez les délimiteurs qui apparaissent encore dans l’expression. Les motifs de sed sont des expressions régulières : la ponctuation littérale peut donc elle aussi nécessiter un échappement.

Utiliser awk pour remplacer du texte en traitant des enregistrements

awk peut remplacer des occurrences pendant le traitement de chaque enregistrement d’entrée. gsub modifie toutes les correspondances dans la chaîne sélectionnée et renvoie le nombre de substitutions ; $0 désigne l’enregistrement courant. Cette commande affiche les enregistrements transformés sans modifier le fichier d’entrée :

Le code et les libellés ou sorties affichés dans cette section restent en anglais.

input=$(mktemp)
trap 'rm -f "$input"' EXIT
printf '%s\n' 'old road, old bridge' > "$input"
awk '{ gsub(/old/, "new", $0); print }' "$input"
new road, new bridge

Redirigez la sortie vers un nouveau chemin si vous souhaitez créer un fichier transformé, et vérifiez que la destination est différente de l’entrée. Les règles d’expressions régulières et de chaînes de remplacement de awk s’appliquent : les caractères spéciaux doivent être traités avec soin lorsque les motifs ne sont pas des littéraux fixes. Choisissez awk lorsque le remplacement s’intègre au traitement d’enregistrements ; pour une simple substitution dans un flux, sed peut être plus facile à lire.

Pièges courants et conseils pratiques

Pour effectuer plusieurs remplacements dans une variable, enchaînez les expansions de paramètres en affectant chaque résultat à la variable suivante, ou effectuez plusieurs substitutions en un seul passage avec sed ou awk. Rendez chaque transformation explicite afin que l’ordre soit clair : un remplacement antérieur peut produire du texte auquel correspond ensuite un motif ultérieur.

Utilisez l’expansion de paramètres lorsque le texte se trouve déjà dans une variable Bash et que les motifs sont simples. Elle évite une commande externe, mais aucune affirmation générale sur les performances ne remplace la mesure de la charge de travail qui vous intéresse. sed convient directement aux substitutions dans des flux organisés en lignes. awk est utile lorsque le remplacement s’accompagne du traitement de champs, de conditions ou d’autres enregistrements. Ces outils ont des règles différentes pour les motifs et les remplacements ; ne supposez donc pas qu’un motif écrit pour l’un peut être repris tel quel dans l’autre.

Avant de modifier un fichier, préservez l’original en écrivant dans une destination distincte ou en créant une sauvegarde. Vérifiez les chemins d’entrée et de sortie, examinez des données représentatives, puis effectuez une modification sur place uniquement si elle est nécessaire. Cette précaution est particulièrement importante avec les motifs larges, car une substitution globale peut toucher chaque occurrence correspondante sur chaque ligne.

Exécutez l’exemple pertinent sur une copie de vos données et examinez le résultat avant de l’appliquer à des fichiers importants. L’article ne fournit aucune comparaison mesurée entre ces méthodes ; choisissez donc en fonction de la forme des données, des besoins de transformation et des exigences de sécurité des fichiers, plutôt que d’un classement supposé de leur vitesse.