Newer
Older
cours-unix-shell / output / sed / README.html
<!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">&#39;s/Dilib/DILIB/&#39;</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">&#39;s/Dilib/DILIB/g&#39;</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">&#39;s/Dilib/DILIB/g&#39;</span> -e <span class="st">&#39;s/Jacques Ducloy/Monsieur Dilib/g&#39;</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">&#39;s/Jacques D[uU][cC][lL][oO][yY]/Monsieur Dilib/g&#39;</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">&#39;s/ré.*duction/réduction/g&#39;</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">&#39;s/^\([A-Z][A-Za-z]*\), \([A-Z][A-Za-z]*\)/\2 \1/&#39;</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 &quot;exemple.sed&quot;</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">&amp;</span><span class="ex">Eacute</span><span class="kw">;</span><span class="ex">/g</span>
        <span class="ex">s</span>/À/<span class="kw">&amp;</span><span class="ex">Agrave</span><span class="kw">;</span><span class="ex">/g</span>
        <span class="ex">s</span>/Ç/<span class="kw">&amp;</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 &quot;exemple2.sed&quot;</span>
        <span class="ex">s</span>/É/<span class="kw">&amp;</span><span class="ex">Eacute</span><span class="kw">;</span><span class="ex">/g</span>
        <span class="ex">s</span>/À/<span class="kw">&amp;</span><span class="ex">Agrave</span><span class="kw">;</span><span class="ex">/g</span>
        <span class="ex">s</span>/Ç/<span class="kw">&amp;</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>&copy; CNRS 2023</p>
    </footer>
</body>

</html>