238 lines
6.6 KiB
XML
238 lines
6.6 KiB
XML
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||
<!DOCTYPE html
|
||
PUBLIC "-//ENS/Tuteurs//DTD TML 1//EN"
|
||
"tuteurs://DTD/tml.dtd">
|
||
<html>
|
||
<head>
|
||
<title>find</title>
|
||
</head>
|
||
<body>
|
||
|
||
<h1>Corrigés des exercices sur <code>find</code></h1>
|
||
|
||
|
||
<p>Ces exercices sont des questions de cours : les solutions se trouvent
|
||
toutes dans les pages de man des commandes en question. On suppose donc
|
||
connues les commandes de <code>less</code>, qui servent à se déplacer dans les
|
||
pages de man... et la commande servant à chercher un mot. Testez les
|
||
commandes sur des fichiers et répertoires d'essai pour vous faire la main et
|
||
comprendre ce qui se passe.
|
||
</p>
|
||
|
||
|
||
<h2>Les options de <code>find</code></h2>
|
||
|
||
|
||
<ol>
|
||
|
||
<li><a name="find1"> <strong>Comment chercher tous les fichiers dont les noms
|
||
commençent par un «a» majuscule ou une minuscule, suivi d'éventuellement
|
||
quelques lettres ou chiffres, et se terminent par un chiffre entre 3 et
|
||
6 ?</strong> </a> <p>
|
||
|
||
|
||
C'est l'option <code>-name</code> qui permet de spécifier le nom du ou des
|
||
fichiers recherchés. On peut indiquer le nom d'un fichier complet
|
||
(<code>bofichier.tex</code>), ou utiliser des expressions régulières (celles du
|
||
shell, pas celles de <code>grep</code>...) :</p>
|
||
|
||
<ul>
|
||
<li> L'étoile (<code>*</code>) désigne «un ou plusieurs caractères»;</li>
|
||
<li> Le point d'interrogation remplace un (et un seul) caractère
|
||
quelconque;</li>
|
||
<li> Les crochets permettent de désigner une série de caractères au
|
||
choix.</li>
|
||
</ul>
|
||
|
||
<p>
|
||
Dans notre cas, le premier caractère est un «a» ou un «A» (<code>[aA]</code>),
|
||
suivi de quelque chose (<code>*</code>) et terminé par un chiffre entre 3 et 6
|
||
(<code>[3456]</code> ou <code>[3-6]</code>). On écrit donc :
|
||
</p>
|
||
|
||
|
||
<pre>
|
||
find . -name '[aA]*[3-6]' -print
|
||
</pre>
|
||
</li>
|
||
|
||
<li><a name="find2"> <strong>Comment fait-on pour indiquer que le fichier
|
||
recherché a été modifié il y a plus de 30 jours ? Il y a 30 jours ?
|
||
Il y a moins de 30 jours?</strong> </a>
|
||
<p>
|
||
C'est l'option <code>-mtime</code> qui permet de donner une indication en
|
||
jours. La syntaxe varie selon ce que l'on souhaite :
|
||
</p>
|
||
|
||
<ul>
|
||
<li> <code>-mtime 30</code> : le fichier a été modifié il y a 30
|
||
jours;</li>
|
||
<li> <code>-mtime +30</code> : le fichier a été modifié il y a 30
|
||
jours ou plus;</li>
|
||
<li> <code>-mtime -30</code> : le fichier a été modifié il y a 30
|
||
jours ou moins.</li>
|
||
</ul></li>
|
||
|
||
<li><a name="find3"> <strong>Comment faire pour dire que le fichier a été
|
||
modifié plus récemment qu'un autre fichier donné ? </strong> </a><p>
|
||
|
||
On utilise l'option <code>-newer</code> («plus récent»). Par exemple, on
|
||
cherche un fichier <code>.tex</code> modifié plus récemment que
|
||
<code>bofichier.tex</code> :
|
||
</p>
|
||
|
||
<pre>
|
||
find . -newer bofichier.tex -name '*.tex'
|
||
</pre>
|
||
|
||
|
||
<p>
|
||
On peut raffiner la demande, en combinant cette option avec l'option
|
||
<code>-mtime</code> : cherchons les fichiers modifiés plus récemment que
|
||
<code>bofichier.tex</code>, mais il y a plus de 5 jours : </p>
|
||
|
||
<pre>
|
||
find . -newer bofichier.tex -mtime +5 -name '*.tex'
|
||
</pre></li>
|
||
|
||
<li><a name="find4"> <strong>Comment fait-on pour spécifier que le fichier
|
||
recherché est un répertoire ? </strong> </a><p>
|
||
On utilise l'option <code>-type</code> pour spécifier le genre de fichier
|
||
recherché : les principaux sont <code>f</code> (<em>file</em>) pour un
|
||
fichier normal, et <code>d</code> (<em>directory</em>) pour un répertoire.
|
||
On tape donc :
|
||
</p>
|
||
|
||
<pre>
|
||
find . -type d
|
||
</pre>
|
||
</li>
|
||
|
||
<li><a name="find5"> <strong>Comment indiquer que le fichier recherché à une
|
||
taille supérieure à une taille donnée ? </strong> </a> <p>
|
||
|
||
On utilise l'option <code>-size</code>, suivie d'un nombre et d'une lettre
|
||
indiquant l'unité de mesure (<code>c</code> : octets,
|
||
<code>k</code> : kilo-octets). Comme pour <code>-mtime</code>, on
|
||
utilise <code>+</code>, <code>-</code> ou <code>[rien]</code> pour indiquer
|
||
que la taille est, respectivement, supérieure, inférieure ou égale à la valeur
|
||
donnée.</p>
|
||
|
||
<p>
|
||
Par exemple, on recherche un fichier modifié il y a moins de 12 jours et dont
|
||
la taille soit supérieure à 30 K : </p>
|
||
|
||
<pre>
|
||
find . -type f -size +30k -mtime -12 -print
|
||
</pre></li>
|
||
|
||
</ol>
|
||
|
||
<h2>Exécuter des commandes sur les fichiers trouvés</h2>
|
||
|
||
<p><a name="find6"> <strong>Utiliser <code>find</code> pour effacer tous vos
|
||
fichiers de sauvegarde (terminés par un tilde) qui ont plus d'un mois.
|
||
</strong> </a></p> <p>
|
||
|
||
|
||
La ligne utilisée pour trouver ces fichiers et la suivante :
|
||
</p>
|
||
|
||
<pre>
|
||
find . -mtime +30 -name '*~'
|
||
</pre>
|
||
|
||
<p>
|
||
Il y a deux façons de faire exécuter des commandes sur les fichiers trouvés
|
||
par <code>find</code> : utiliser l'option «<code>-exec</code>
|
||
<em>commande</em>», ou utiliser un pipe avec <code>xargs</code>.
|
||
</p>
|
||
|
||
<ol>
|
||
|
||
<li> <strong><code>-exec</code> <em>commande</em></strong> exécute la commande
|
||
sur le fichier courant. La commande est terminée par le marqueur
|
||
<code>;</code>, qu'il faut protéger du shell avec un backslash. Le fichier
|
||
courant est désigné par la chaîne <code>{}</code>.
|
||
|
||
<p>
|
||
Pour effacer tous les fichiers de sauvegarde vieux de plus d'un mois, on tape
|
||
donc : </p>
|
||
|
||
<pre>
|
||
find . -mtime +30 -name '*~' -print -exec rm \;
|
||
</pre>
|
||
|
||
|
||
<p>
|
||
On peut faire exécuter la commande de façon interactive en remplaçant
|
||
<code>-exec</code> par <code>-ok</code> : </p>
|
||
|
||
<pre>
|
||
find . -mtime +30 -name '*~' -print -ok rm \;
|
||
</pre>
|
||
|
||
<p>
|
||
Le programme demande, pour chaque fichier trouvé, si on veut bien exécuter la
|
||
commande; la réponse doit être «<code>y</code>» ou «<code>Y</code>».
|
||
</p></li>
|
||
|
||
<li> La solution avec <code>-exec</code> est en fait très lourde, car elle
|
||
crée un nouveau processus pour chaque fichier; il vaut mieux
|
||
<strong>rediriger le résultat de <code>find</code> avec un pipe et
|
||
<code>xargs</code></strong>. Dans notre cas, on tapera donc :
|
||
|
||
|
||
<pre>
|
||
find . mtime +30 -name '*~' | xargs -p rm
|
||
</pre>
|
||
|
||
<p>
|
||
L'option <code>-p</code> de <code>xargs</code> rend cette commande
|
||
interactive. Il faut répondre «<code>y</code>» ou «<code>Y</code>» pour
|
||
confirmer.
|
||
</p></li>
|
||
|
||
</ol>
|
||
|
||
<p>
|
||
Quelle différence y a-t-il entre un simple pipe et
|
||
«<code>| xargs</code>» ? Pour la comprendre, voici un
|
||
exercice : cherchez tous les fichiers contenus dans
|
||
<code>/usr/local/lib/texmf/tex</code> et cherchez dedans le mot «supertab». Il
|
||
y a deux solutions :
|
||
</p>
|
||
|
||
<ol>
|
||
|
||
<li> Vous tapez
|
||
|
||
<pre>
|
||
find /usr/local/lib/texmf/tex -type f | grep supertab
|
||
</pre>
|
||
|
||
<p>
|
||
Vous obtenez une liste de fichiers contenant «supertab» dans leur nom.
|
||
</p>
|
||
</li>
|
||
|
||
<li> Vous tapez
|
||
<pre>
|
||
find /usr/local/lib/texmf/tex -type f | xargs grep supertab
|
||
</pre>
|
||
|
||
<p>
|
||
<code>grep</code> cherche dans chaque fichier passé en argument la chaîne de
|
||
caractères «supertab», ce qui est très différent...</p></li>
|
||
|
||
|
||
</ol>
|
||
|
||
|
||
<div class="metainformation">
|
||
Auteur : Émilia Robin, Joël Riou. Dernière modification le 2002-12-09.
|
||
</div>
|
||
|
||
</body>
|
||
</html>
|
||
|