<!DOCTYPE html>
<html>
<head>
<title></title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<header>
<h1></h1>
<nav>
<ul>
<li><a href="/output/README.html">Accueil</a></li>
<li><a href="/output/unix/README.html">UNIX</a></li>
<li><a href="/output/bases/README.html">Bases</a></li>
<li><a href="/output/commandes/README.html">Commandes</a></li>
<li><a href="/output/shell/README.html">Shell</a></li>
<li><a href="/output/sed/README.html">Sed</a></li>
<li><a href="/output/make/README.html">Make</a></li>
</ul>
</nav>
</header>
<div class="content">
<h1 id="sed---unix">sed - UNIX</h1>
<p>Sed (pour <strong>S</strong>tream <strong>ED</strong>itor) est un éditeur non interactif de texte.<br />
Il permet d'appliquer une certain nombre de commandes à un fichier puis d'en afficher le résultat (sans modifier le fichier de départ) sur la sortie standard.<br />
Comme avec toute commande unix, il est possible de rediriger la sortie vers un fichier résultat.</p>
<h2 id="substitution">Substitution</h2>
<p>La commande suivante lit un fichier <code>file.txt</code> et affiche ses lignes sur la sortie standard en remplaçant la chaîne « <code>Dilib</code> » par la chaîne « <code>DILIB</code> ».</p>
<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash"><span class="fu">sed</span> <span class="st">'s/Dilib/DILIB/'</span> file.txt</code></pre></div>
<p>Il est conseillé d'entourer les commandes par des apostrophes simples, pour éviter que le shell n'interprète les <a href="../shell/parametres.html#caractères-spéciaux">caractères spéciaux</a> (<code>.*[]^$\</code>).</p>
<blockquote>
<p>⚠ Cette commande ne remplace que la première occurrence de « <code>Dilib</code> » sur chaque ligne du fichier.<br />
S'il y en a deux, la deuxième ne sera pas remplacée, à moins d'utiliser l'option <code>g</code> en fin de commande :</p>
<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash"><span class="fu">sed</span> <span class="st">'s/Dilib/DILIB/g'</span> file.txt</code></pre></div>
</blockquote>
<p>Si on veut faire deux remplacements sur la même ligne de commandes, on peut utiliser :</p>
<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash"><span class="fu">sed</span> -e <span class="st">'s/Dilib/DILIB/g'</span> -e <span class="st">'s/Jacques Ducloy/Monsieur Dilib/g'</span> file.txt</code></pre></div>
<blockquote>
<p>⚠ Le <code>-e</code> est obligatoire pour distinguer la deuxième commande d'un nom de fichier qui n'en est jamais précédé.</p>
<p>📗 Les commandes sont effectuées sur chaque ligne dans leur ordre d'apparition, ce qui veut dire que « <code>Jacques Ducloy</code> » sera transformé en « <code>Monsieur Dilib</code> » après la substitution de « <code>Dilib</code> » par « <code>DILIB</code> », il restera donc des « <code>Dilib</code> » sur la sortie standard.</p>
</blockquote>
<h3 id="rappel-sur-les-expressions-régulières">Rappel sur les expressions régulières</h3>
<table>
<colgroup>
<col style="width: 8%" />
<col style="width: 91%" />
</colgroup>
<tbody>
<tr class="odd">
<td><code>^</code></td>
<td>début de ligne</td>
</tr>
<tr class="even">
<td><code>$</code></td>
<td>fin de ligne</td>
</tr>
<tr class="odd">
<td><code>[]</code></td>
<td>classe de caractères (exemples : <code>[A-Z]</code> correspond à toutes les lettres majuscules)</td>
</tr>
<tr class="even">
<td><code>[^...]</code></td>
<td>classe de caractères correspondant à n'importe quels caractères sauf ceux qui suivent le caractère <code>^</code></td>
</tr>
<tr class="odd">
<td></td>
<td>Exemple : <code>[^:]</code> correspond à tous les caractères sauf le <code>:</code>.</td>
</tr>
<tr class="even">
<td><code>*</code></td>
<td>le caractère précédant <code>*</code> répété de 0 à n fois</td>
</tr>
<tr class="odd">
<td><code>+</code></td>
<td>le caractère précédant <code>+</code> répété de 1 à n fois</td>
</tr>
<tr class="even">
<td><code>?</code></td>
<td>le caractère précédant <code>?</code> présent de 0 à 1 fois</td>
</tr>
</tbody>
</table>
<h3 id="expressions-régulières">Expressions régulières</h3>
<p>On peut utiliser des expressions régulières dans les chaînes à remplacer (donc, il faut banaliser les caractères spéciaux dans cette chaîne).</p>
<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash"><span class="fu">sed</span> -e <span class="st">'s/Jacques D[uU][cC][lL][oO][yY]/Monsieur Dilib/g'</span> fichier</code></pre></div>
<blockquote>
<p>📗 Le caractère <code>*</code> englobe autant de caractères qu'il peut, ce qui veut dire que</p>
<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash"><span class="fu">sed</span> <span class="st">'s/ré.*duction/réduction/g'</span> fichier</code></pre></div>
<p>transformera le fichier</p>
<pre class="txt"><code>do ré mi fa sol la si duction ah bon duction la suite</code></pre>
<p>en</p>
<pre class="txt"><code>do réduction la suite</code></pre>
<p>et non en</p>
<pre class="txt"><code>do réduction ah bon duction la suite</code></pre>
</blockquote>
<h2 id="récupération">Récupération</h2>
<p>Les opérateurs <code>\(</code> et <code>\)</code> sauvent leur contenu et permettent leur récupération par l'utilisation de <code>\1</code>, <code>\2</code>, etc.</p>
<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash"><span class="fu">sed</span> -e <span class="st">'s/^\([A-Z][A-Za-z]*\), \([A-Z][A-Za-z]*\)/\2 \1/'</span> fichier</code></pre></div>
<p>Remplacera les « <code>Nom, Prénom</code> » en début de chaque ligne du fichier (quand il en trouve) par « <code>Prénom Nom</code> ».</p>
<h2 id="fichier-de-commandes">Fichier de commandes</h2>
<p>Si vous avez beaucoup de commandes, vous pouvez les rassembler dans un fichier comme celui-là :</p>
<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash"><span class="co"># Fichier "exemple.sed"</span>
<span class="co"># Il ne peut y avoir de commentaires que dans un bloc au début du</span>
<span class="co"># fichier.</span>
<span class="ex">s</span>/É/<span class="kw">&</span><span class="ex">Eacute</span><span class="kw">;</span><span class="ex">/g</span>
<span class="ex">s</span>/À/<span class="kw">&</span><span class="ex">Agrave</span><span class="kw">;</span><span class="ex">/g</span>
<span class="ex">s</span>/Ç/<span class="kw">&</span><span class="ex">Ccedil</span><span class="kw">;</span><span class="ex">/g</span></code></pre></div>
<p>Pour appeler ce fichier, il faut utiliser l'option <code>-f</code> :</p>
<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash"><span class="fu">sed</span> -f exemple.sed fichier</code></pre></div>
<p>Une autre solution consiste à en faire un script exécutable (à la manière d'un script shell) :</p>
<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash"><span class="co">#!/usr/bin/sed -f</span>
<span class="co"># Table de transcodage de ISO-8859-1 vers HTML</span>
<span class="co"># Fichier "exemple2.sed"</span>
<span class="ex">s</span>/É/<span class="kw">&</span><span class="ex">Eacute</span><span class="kw">;</span><span class="ex">/g</span>
<span class="ex">s</span>/À/<span class="kw">&</span><span class="ex">Agrave</span><span class="kw">;</span><span class="ex">/g</span>
<span class="ex">s</span>/Ç/<span class="kw">&</span><span class="ex">Ccedil</span><span class="kw">;</span><span class="ex">/g</span></code></pre></div>
<p>Mais il ne faut pas oublier de lui donner les droits en exécution, pour pouvoir l'appeler ainsi :</p>
<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash"><span class="fu">chmod</span> u+x exemple2.sed
<span class="ex">./exemple2.sed</span> fichier</code></pre></div>
<blockquote>
<p>⚠ Un fichier de commandes sed doit toujours se terminer par un passage à la ligne, sinon la dernière commande n'est pas prise en compte!</p>
</blockquote>
<blockquote>
<p>⚠ De la même manière, toutes les lignes à traiter doivent finir par un retour à la ligne (en particulier la dernière)!</p>
</blockquote>
<h2 id="référence">Référence</h2>
<ul>
<li><a href="http://www.shellunix.com/sed.html" class="uri">http://www.shellunix.com/sed.html</a> La commande <strong>sed</strong></li>
<li><a href="https://regex101.com/" class="uri">https://regex101.com/</a> <strong>Regex 101</strong>, pour fabriquer et comprendre vos expressions régulières</li>
<li><a href="https://jex.im/regulex/" class="uri">https://jex.im/regulex/</a> <strong>Regulex</strong>, pour visualiser la structure des expressions régulières</li>
<li><a href="https://github.com/regexhq" class="uri">https://github.com/regexhq</a> <strong>RegexHQ</strong> pour trouver facilement des expressions régulières pour toutes sortes de cas d'usages</li>
</ul>
<p><a href="../shell/tp.html">Précédent</a> - <a href="./tp.html">Suivant</a></p>
</div>
<footer>
<p>© CNRS 2023</p>
</footer>
</body>
</html>