diff --git a/commandes/tp.md b/commandes/tp.md index 7cc544d..de7ef74 100644 --- a/commandes/tp.md +++ b/commandes/tp.md @@ -299,4 +299,4 @@ -[Précédent](./processus.md) - [Suivant](./shell/README.md) +[Précédent](./processus.md) - [Suivant](../shell/README.md) diff --git a/sed/README.md b/sed/README.md new file mode 100644 index 0000000..3f8acc4 --- /dev/null +++ b/sed/README.md @@ -0,0 +1,160 @@ +# sed - UNIX + +Sed (pour **S**tream **ED**itor) est un éditeur non interactif de texte. +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. +Comme avec toute commande unix, il est possible de rediriger la sortie vers un +fichier résultat. + +## Substitution + +La commande suivante lit un fichier `file.txt` et affiche ses lignes sur la +sortie standard en remplaçant la chaîne « `Dilib` » par la chaîne « `DILIB` ». + +```bash +sed 's/Dilib/DILIB/' file.txt +``` + +Il est conseillé d'entourer les commandes par des apostrophes simples, pour +éviter que le shell n'interprète les [caractères +spéciaux](../shell/parametres.md#caractères-spéciaux) (`.*[]^$\`). + +> ⚠ Cette commande ne remplace que la première occurrence de « `Dilib` » sur chaque +> ligne du fichier. +> S'il y en a deux, la deuxième ne sera pas remplacée, à moins d'utiliser +> l'option `g` en fin de commande : +> +> ```bash +> sed 's/Dilib/DILIB/g' file.txt +> ``` + +Si on veut faire deux remplacements sur la même ligne de commandes, on peut utiliser : + +```bash +sed -e 's/Dilib/DILIB/g' -e 's/Jacques Ducloy/Monsieur Dilib/g' file.txt +``` + +> ⚠ Le `-e` est obligatoire pour distinguer la deuxième commande d'un nom de +> fichier qui n'en est jamais précédé. +> +> 📗 Les commandes sont effectuées sur chaque ligne dans leur ordre +> d'apparition, ce qui veut dire que « `Jacques Ducloy` » sera transformé en « +> `Monsieur Dilib` » après la substitution de « `Dilib` » par « `DILIB` », il +> restera donc des « `Dilib` » sur la sortie standard. + +### Rappel sur les expressions régulières + +| | | +| -------- | ------------------------------------------------------------------------------------------------------ | +| `^` | début de ligne | +| `$` | fin de ligne | +| `[]` | classe de caractères (exemples : `[A-Z]` correspond à toutes les lettres majuscules) | +| `[^...]` | classe de caractères correspondant à n'importe quels caractères sauf ceux qui suivent le caractère `^` | +| | Exemple : `[^:]` correspond à tous les caractères sauf le `:`. | +| `*` | le caractère précédant `*` répété de 0 à n fois | +| `+` | le caractère précédant `+` répété de 1 à n fois | +| `?` | le caractère précédant `?` présent de 0 à 1 fois | + +### Expressions régulières + +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). + +```bash +sed -e 's/Jacques D[uU][cC][lL][oO][yY]/Monsieur Dilib/g' fichier +``` + +> 📗 Le caractère `*` englobe autant de caractères qu'il peut, ce qui veut dire que +> +> ```bash +> sed 's/ré.*duction/réduction/g' fichier +> ``` +> +> transformera le fichier +> +> ```txt +> do ré mi fa sol la si duction ah bon duction la suite +> ``` +> +> en +> +> ```txt +> do réduction la suite +> ``` +> +> et non en +> +> ```txt +> do réduction ah bon duction la suite +> ``` + +## Récupération + +Les opérateurs `\(` et `\)` sauvent leur contenu et permettent leur récupération +par l'utilisation de `\1`, `\2`, etc. + +```bash +sed -e 's/^\([A-Z][A-Za-z]*\), \([A-Z][A-Za-z]*\)/\2 \1/' fichier +``` + +Remplacera les « `Nom, Prénom` » en début de chaque ligne du fichier (quand il +en trouve) par « `Prénom Nom` ». + +## Fichier de commandes + +Si vous avez beaucoup de commandes, vous pouvez les rassembler dans un fichier +comme celui-là : + +```bash +# Fichier "exemple.sed" +# Il ne peut y avoir de commentaires que dans un bloc au début du +# fichier. +s/É/É/g +s/À/À/g +s/Ç/Ç/g +``` + +Pour appeler ce fichier, il faut utiliser l'option `-f` : + +```bash +sed -f exemple.sed fichier +``` + +Une autre solution consiste à en faire un script exécutable (à la manière d'un +script shell) : + +```bash +#!/usr/bin/sed -f +# Table de transcodage de ISO-8859-1 vers HTML +# Fichier "exemple2.sed" +s/É/É/g +s/À/À/g +s/Ç/Ç/g +``` + +Mais il ne faut pas oublier de lui donner les droits en exécution, pour pouvoir +l'appeler ainsi : + +```bash +chmod u+x exemple2.sed +./exemple2.sed fichier +``` + +> ⚠ 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! + +> ⚠ De la même manière, toutes les lignes à traiter doivent finir par un retour +> à la ligne (en particulier la dernière)! + +## Référence + +- La commande **sed** +- **Regex 101**, pour fabriquer et comprendre vos + expressions régulières +- **Regulex**, pour visualiser la structure des + expressions régulières +- **RegexHQ** pour trouver facilement des expressions + régulières pour toutes sortes de cas d'usages + +[Précédent](../shell/tp.md) - [Suivant](./tp.md) diff --git a/sed/tp.md b/sed/tp.md new file mode 100644 index 0000000..06f72d5 --- /dev/null +++ b/sed/tp.md @@ -0,0 +1,99 @@ +# Travaux pratiques - Sed - UNIX + +## Utilisation simple + +Écrivez une commande `sed` transformant la chaîne « `moins` » en « `plus` ». +Appliquez-la à « `Vous aurez moins de budget` ». + +
+Voir la solution + +```bash +sed -e 's/moins/plus/g' +``` + +
+ +## Utilisation d'un fichier de commandes + +Écrivez un commande `sed` transformant toutes les lettres minuscules en leur +suivante lexicographique (cas particulier : `z` se transforme en `!`). +Rappel : vous pouvez utiliser un fichier pour rassembler plusieurs commandes `sed`. + +
+Voir la solution + +```bash +sed -f decalage.sed +``` + +```bash +# fichier "decalage.sed" +s/z/!/g +s/y/z/g +s/x/y/g +s/w/x/g +s/v/w/g +s/u/v/g +s/t/u/g +s/s/t/g +s/r/s/g +s/q/r/g +s/p/q/g +s/o/p/g +s/n/o/g +s/m/n/g +s/l/m/g +s/k/l/g +s/j/k/g +s/i/j/g +s/h/i/g +s/g/h/g +s/f/g/g +s/e/f/g +s/d/e/g +s/c/d/g +s/b/c/g +s/a/b/g +``` + +> 📗 Cette solution peut sembler étrange, car les substitutions ne se font pas +> dans l'ordre alphabétique mais dans l'ordre alphabétique inverse. +> C'est nécessaire car sinon tous les `a` se transforment en `b`, puis tous les +> `b` (y compris ceux qui sont nouvellement transformés) en `c`, *etc*., pour +> finir par un texte intégralement composé de lettres `a`. + +
+ +## Substitution en début de ligne + +Écrivez une commande `sed` qui affiche uniquement le début de chaque ligne du +fichier `/etc/passwd` jusqu'au premier caractère `:`. + +
+Voir la solution + +```bash +sed -e 's/^\([^:]*\).*$/\1/' /etc/passwd +``` + +> 📗 On aurait pu aussi utiliser la commande `cut`. + +
+ +## Substitution dans toute la ligne + +Écrivez une commande `sed` qui remplace les couples de guillemets anglais par un +couple de guillemets français (`Ceci est un "exemple" qui doit "fonctionner".` +doit donner `Ceci est un <> qui doit <>.`). + +
+Voir la solution + +```bash +sed -e 's/"\([^"]*\)"/<<\1>>/g' +``` + +
+ +[Précédent](./README.md) - [Suivant](../make/README.md) diff --git a/shell/README.md b/shell/README.md new file mode 100644 index 0000000..8720094 --- /dev/null +++ b/shell/README.md @@ -0,0 +1,50 @@ +# Variables d'environnement - Shell - UNIX + +Le shell contient diverses variables d'environnement. +Si vous voulez les voir toutes, utilisez la commande `set` ou la commande `env` sans paramètre. + +Certaines de ces variables peuvent nous intéresser plus particulièrement (pour +visualiser leur contenu, utilisez la commande `echo`, par exemple `echo $HOME` +pour afficher le contenu de la variable `HOME`) : + +| nom | contenu | +| ----- | -------------------------------------------------------------------------------------------------------------------------- | +| HOME | chemin de votre *home directory* | +| PATH | liste des chemins parcourus par le shell pour trouver les commandes à exécuter (quand le chemin complet n'est pas précisé) | +| PS1 | "Prompt" utilisé dans le shell (on peut modifier sa valeur) | +| SHELL | indique le shell qu'on utilise | +| USER | votre nom d'utilisateur | + +Pour modifier la valeur d'une variable (ou en créer une), il suffit d'utiliser la syntaxe : + +```bash +VARIABLE=valeur +``` + +> ⚠ Il ne faut pas mettre d'espace autour du caractère `=` + +Par convention, les noms de variable sont en majuscules. +Pour accéder à la valeur d'une variable, on utilise : + +```bash +$VARIABLE +``` + +ou, pour éviter des ambiguités (si `a="var"`, `${a}b` renvoie `varb` alors que `$ab` est invalide) : + +```bash +${VARIABLE} +``` + +On peut créer des variables utilisateurs de la même manière. + +Une variable n'est disponible que dans le shell où on l'a initialisée. + +Faire précéder l'affectation d'une variable du mot-clé `export` autorise son +utilisation dans un shell différent. + +```bash +export VARIABLE=valeur +``` + +[Précédent](../commandes/tp.md) - [Suivant](./scripts.md) diff --git a/shell/commandes.md b/shell/commandes.md new file mode 100644 index 0000000..d4f838f --- /dev/null +++ b/shell/commandes.md @@ -0,0 +1,33 @@ +# Commandes diverses - Shell - UNIX + +## Commandes + +| | | +| ---------------- | ----------------------------------------------------------------------------------------------------- | +| `#` | commentaires (mais `#!/bin/sh` en début de fichier est le shebang) | +| `( commande )` | exécute la commande dans un sous-shell | +| `read a` | lecture d'une entrée pendant l'exécution d'un script | +| `exit num` | renvoie le statut du script au shell appelant | +| `. script` | inclusion et exécution du script dans le shell courant | +| `exec script` | exécute le script dans un nouveau shell | +| `cmd1 \|\| cmd2` | séparateur conditionnel (`cmd2` est exécutée même si `cmd1` ne s'est pas exécutée correctement) | +| `cmd1 && cmd2` | séparateur conditionnel (`cmd2` est exécutée seulement si `cmd1` s'est exécutée correctement) | +| `set` | liste de toutes les variables. | +| | Positionne les paramètres `$i` (`set a b c` positionne `$1` à `a`, `$2` à `b` et `$3` à `c`). | +| `unset var` | remise à zéro de la variable `var` | +| `type cmde` | indique la nature (et la localisaton) d'une commande | +| `alias al='cmd'` | crée une commande al équivalente à la commande `cmd` (qui peut être complexe) | +| `touch fichier` | change la date de dernière modification du fichier. Si le fichier n'existe pas, crée un fichier vide. | + +## expr + +`expr` exécute des opérations arithmétiques sur des entiers (l'opérateur peut +être `+`, `-`, `\*`, `/`, `%`, `=`, `\>`, `\<`, `\>=`, `\<=`, `!=`). + +L'expression est une commande, donc pour affecter une opération à une variable, il faut forcer son exécution avec des antiquotes (`AltGr`-`7`) : + +```bash +a=`expr $b + $c` +``` + +[Préédent](./controle.md) - [Suivante](./tp.md) diff --git a/shell/conditions.md b/shell/conditions.md new file mode 100644 index 0000000..833f2e7 --- /dev/null +++ b/shell/conditions.md @@ -0,0 +1,78 @@ +# Conditions - Shell - UNIX + +Les commandes `if`, `while`, et `until` testent le statut de la commande qu'ils +ont en paramètre. + +## if + +### Syntaxe + +```bash +if commande +then + liste_commandes +[elif commande + then + liste_commandes] ... +[else liste_commandes] +fi +``` + +### Exemples + +```bash +if test -f $1 +then + cat $1 +else + echo "Le fichier \"$1\" n'existe pas" +fi +``` + +## test + +`test` est une commande qui renvoie une valeur vraie ou fausse (`0` pour vrai, +`1` pour fausse). +Elle a différentes options permettant de tester différentes conditions sur des +fichiers, des valeurs (chaînes de caractères), etc. + +Sa syntaxe est `test expr` ou `[ expr ]` (attention, il faut un espace après `[` et avant `]`). + +| expr | signification | +| ---------------- | -------------------------------------------------------------------------------- | +| `-r fichier` | vrai si le `fichier` existe et est accessible en lecture (r) | +| `-w fichier` | vrai si le `fichier` existe et est accessible en écriture (w) | +| `-x fichier` | vrai si le `fichier` existe et est exécutable (x) | +| `-f fichier` | vrai si le `fichier` existe et est un fichier "régulier" (file) | +| `-d fichier` | vrai si le `fichier` existe et est un répertoire (directory) | +| `-s fichier` | vrai si le `fichier` existe et a une taille non nulle (size) | +| `c1 = c2` | vrai si les deux expressions sont égales (des chaînes, en sh) | +| `c1 != c2` | vrai si les deux expressions sont différentes (des chaînes, en sh) | +| `c1` | vrai si `c1` n'est pas la chaîne nulle (vide) | +| `e1 -eq e2` | vrai si les deux entiers `e1` et `e2` sont algébriquement égaux (equal) | +| `e1 -ne e2` | vrai si les deux entiers `e1` et `e2` sont algébriquement différents (not equal) | +| `e1 -gt e2` | vrai si l'entier `e1` est plus grand que l'entier `e2` (greater than) | +| `e1 -lt e2` | vrai si l'entier `e1` est plus petit que `e2` (lower than) | +| `! expr` | négation de l'expression booléenne `expr` | +| `expr1 -a expr2` | et logique entre les deux expressions booléennes `expr1` et `expr2` (and) | +| `expr1 -o expr2` | ou logique entre les deux expressions booléennes `expr1` et `expr2` (or) | + +### Exemples + +Quand `script.sh` est un fichier qui existe dans le répertoire courant. + +```bash +$ test -f script.sh +$ echo $? +0 +``` + +Quand `inexistant.sh` est un fichier qui n'est pas dans le répertoire courant. + +```bash +$ test -f inexistant.sh +$ echo $? +1 +``` + +[Précédent](./parametres.md) - [Suivant](./controle.md) diff --git a/shell/controle.md b/shell/controle.md new file mode 100644 index 0000000..c268c26 --- /dev/null +++ b/shell/controle.md @@ -0,0 +1,99 @@ +# Structures de contrôle - Shell - UNIX + +## for + +### Syntaxe + +```bash +for var [in liste] +do + liste_commandes +done +``` + +La variable `var` prend successivement les valeurs de la liste. +Si la liste est omise, `var` prend alors les valeurs passées en paramètres du script ([`$*`](./parametres.md#variables-spéciales)). + +### Exemples + +```bash +for i +do + echo $i +done +``` + +```bash +for i in `ls` +do + cp $i /dir/$i + echo "$i copié" +done +``` + +Il ne faut pas oublier les apostrophes inversées (ou quotes inverses) `` ` `` +qui forcent l'exécution du `ls`. + +## while + +### Syntaxe + +```bash +while commande +do + liste_commandes +done +``` + +### Exemple + +```bash +while read a +do + echo $a >> resultat.txt + echo Appuyez sur Ctrl-D pour arrêter. +done +``` + +## until + +### Syntaxe + +```bash +until commande +do + liste_commandes +done +``` + +### Exemple + +```bash +until ! read a +do + echo $a >> resultat.txt + echo Appuyez sur Ctrl-D pour arrêter. +done +``` + +## case + +### Syntaxe + +```bash +case para in + choix1[|choix2] ... ) liste_commandes ;; +esac +``` + +### Exemple + +```bash +case $1 in + bonjour ) echo "Bonjour aussi." ;; + A+ | a+ ) echo "À bientôt." ;; + * ) echo "Je n'ai pas bien compris le paramètre \"$1\".";; +esac +``` + +[Précédent](./conditions.md) - [Suivant](./commandes.md) diff --git a/shell/parametres.md b/shell/parametres.md new file mode 100644 index 0000000..494fa3b --- /dev/null +++ b/shell/parametres.md @@ -0,0 +1,41 @@ +# Paramètres - Shell - UNIX + +## Récupération des paramètres de la ligne de commande + +| | | +| ---- | ------------------------------------ | +| `$0` | nom de la commande | +| `$n` | valeur du nième paramètre | +| `$#` | nombre de paramètres | +| `$*` | liste de tous les paramètres | + +Pour la ligne de commande `sh test.sh a b c`, `$0` vaut `test.sh`, `$#` vaut +`3`, `$*` vaut `a b c`, et `$2` vaut `b` (à l'intérieur du script). + +La commande `shift` décale les paramètres (en perdant le premier) : le deuxième +paramètre devient le premier, le troisième devient le deuxième, etc. (c'est +utile quand on utilise une boucle pour traiter les paramètres). + +## Variables spéciales + +| | | +| ---- | ------------------------------------------------------------ | +| `$$` | numéro de processus de la dernière commande | +| `$?` | statut de la dernière commande (`0` = tout s'est bien passé) | + +## Caractères spéciaux + +Comme à chaque fois qu'on a un caractère spécial (par exemple `$`), on a des +caractères d'échappement. + +| | | | | +| ------------- | ------------------------------------------------ | ---------------- | ------------------------------ | +| `\` | banalise le caractère suivant | `echo \$0 $0` | `$0 /usr/bin/ksh` | +| `" ... "` | banalise les caractères sauf `\`, `$` et `` ` `` | `echo "\$0 $0"` | `$0 /usr/bin/ksh` | +| `' ... '` | banalise tous les caractères | `echo '\$0 $0'` | `\$0 $0` | +| `` ` ... ` `` | substitution de commande | ``echo `date` `` | `Mon May 5 16:54:14 MEST 2003` | + +> 💡 En 2023, il est conseillé d'utiliser `$(commande)` pour la substitution de commande. +> L'exemple devient ainsi `echo $(date)`. + +[Précédent](./scripts.md) - [Suivant](conditions.md) diff --git a/shell/scripts.md b/shell/scripts.md new file mode 100644 index 0000000..cf57b5a --- /dev/null +++ b/shell/scripts.md @@ -0,0 +1,33 @@ +# Scripts - Shell -UNIX + +Un fichier script contenant des commandes shell (par exemple des initialisations +de variables, une automatisation de tâches,...) peut être exécuté : + +- soit par `sh nom_fichier_shell`, +- soit par `. nom_fichier_shell` (la différence avec la manière précédente est + que c'est comme si on tapait le contenu du fichier dans le shell courant, et + non comme si on lançait un autre shell, c'est important par exemple pour les + définitions de variables), +- soit en rendant le fichier exécutable (`chmod u+x nom_fichier_shell`), puis en + tapant le nom du fichier (cela fonctionne uniquement quand le répertoire + courant, `.`, est dans `$PATH`, sinon il faut dire au shell que c'est le + fichier qui est dans le répertoire courant qu'on veut exécuter : + `./nom_fichier_shell`). + +Pour être sûr du shell qui est en train de s'exécuter dans un fichier de script shell, il est plus prudent d'ajouter son nom en début de fichier la ligne (par exemple, ici sh) : + +```bash +#!/bin/sh +``` + +Cette ligne a la forme d'un commentaire (elle commence par `#`), on l'appelle un +*shebang*, et signale au shell appelant qu'il faut utiliser le shell `/bin/sh` +pour exécuter le fichier. +Ce *shebang*, qui est un en-tête, doit se mettre sur la première ligne. + +Une seconde ligne peut être intéressante car elle peut influer sur l'ordre de +tri avec `sort` par exemple. +Pour garantir un ordre de tri lexicographique, on peut positionner la variable +d'environnement suivante comme suit `export LC_COLLATE=C`. + +[Précédent](./README.md) - [Suivant](./parametres.md) diff --git a/shell/tp.md b/shell/tp.md new file mode 100644 index 0000000..9cffedf --- /dev/null +++ b/shell/tp.md @@ -0,0 +1,187 @@ +# Travaux pratiques - Shell - UNIX + +> ⚠ Tous les shells qui seront créés par la suite devront avoir le droit +> d'exécution correctement positionné, au moins pour leur propriétaire. + +## Recherche d'information sur un utilisateur + +1. Écrivez un script shell `infouser.sh` qui permette de chercher si un + utilisateur d'un nom donné existe sur votre machine, en affichant sa + référence complète (c'est-à-dire sans aucun filtrage). + Le nom recherché sera passé comme paramètre au shell. + La recherche portera dans le fichier `/etc/passwd`. + +
+ Voir la solution + + > ⚠ Comme d'habitude quand on veut traiter un fichier, il vaut mieux + > visionner son contenu, avant de vouloir l'exploiter (`more /etc/passwd`). + + ```bash + #!/bin/sh + grep $1 /etc/passwd + ``` + + + +2. Modifiez ce shell pour qu'il teste si un paramètre est bien passé en ligne. + En cas d'erreur (aucun paramètre ou plus d'un), un message sera affiché + expliquant la bonne syntaxe à suivre. + +
+ Voir la solution + + ```bash + #!/bin/sh + + if test $# -ne 1 + then + echo Mauvais nombre de parametres. + echo + echo Usage: $0 uid + exit 1 + fi + + grep $1 /etc/passwd + ``` + +
+ +## Quelques manipulations sur un corpus XML + +Pour cette partie du TP, il vous faut d'abord récupérer le corpus suivant : +[`francis.exodic.xml`](../UnixShell_cours2018/francis.exodic.xml) + +Ce fichier contient 20 notices en XML Exodic, dans une forme indentée, son +exploration préparatoire est conseillée. + +1. Écrivez un script shell qui compte le nombre de notices, en passant le nom de + fichier en paramètre. + L'élément racine se nomme `exodic`. + +
+ Voir la solution + + ```bash + #!/bin/sh + + if test $# -ne 1 + then + echo Mauvais nombre de parametres. + echo + echo Usage: $0 fichier + exit 1 + fi + + NB_NOTICES=`cat $1 | grep " + +2. Modifiez le shell précédent pour qu'il teste en plus l'existence du fichier + demandé avant traitement, puis pour qu'il sorte les résultats dans un fichier + nommé `resultats.txt`. + +
+ Voir la solution + + ```bash + #!/bin/sh + + if test $# -ne 1 + then + echo Mauvais nombre de parametres. + echo + echo Usage: $0 fichier + exit 1 + fi + + if test ! -f $1 + then + echo $1 "n'existe pas (ou n'est pas un fichier)." + exit 2 + fi + + NB_NOTICES=`cat $1 | grep " resultats.txt + ``` + + > ⚠ Cette fois, on a mis la chaîne contenant les apostrophes (caractère + > spécial) entre guillemets pour les banaliser. + +
+ +3. Installer et parcourir des fichiers dublin core d'un arbre de répertoires + pour afficher le type de document des notices qui y sont présentes. + Il faut d'abord récupérer le fichier + [`data_dc.tar.gz`](../UnixShell_cours2018/data_dc.tar.gz). + + Votre shell devra décompresser puis installer l'archive du fichier tar sous + `Formation/TP_dc`. + Cela donnera un répertoire `dc` contenant 5 répertoires nommés de 1 à 5. + Ces sous-répertoires contiennent chacun un fichier `dublin_core.xml` avec + une seule notice (qu'il est conseillé d'aller regarder). + + Ces opérations réalisées, la suite du shell devra chercher le type de + document de chaque notice, identifiable avec `dcvalue element="type"`. + Cette information trouvée, les résultats seront écrits dans le fichier + `typesDC.txt`. + +
+ Voir la solution + + ```bash + #!/bin/sh + + # En etant dans le repertoire Formation/TP_dc + gunzip data_dc.tar.gz + tar -xvf data_dc.tar + + for FILE in dc/*/*.xml + do + cat $FILE | grep 'dcvalue element="type"' >> typesDC.txt + done + ``` + + > ⚠ Cette fois, on a mis la chaîne contenant les guillemets (caractère spécial) + > entre apostrophes pour les banaliser. + + > ⚠ On utilise une double redirection en sortie `>>` car il faut concaténer les + > différentes opérations d'écriture dans le fichier résultat. +
+ +4. Écrivez un script shell qui utilise un fichier de clés de sélection avec + `grep` sur un fichier de DOI, pour récupérer chaque sélection dans un fichier + résultat différent. + Les noms de ces fichiers résultats contiendront la valeur de la clé de sélection. + Le fichier de clés est [`listeCles.txt`](../UnixShell_cours2018/listeCles.txt). + Le fichier à filtrer est [`listeDOI.txt.gz`](../UnixShell_cours2018/listeDOI.txt.gz). + +
+ Voir la solution + + ```bash + #!/bin/sh + + export LC_COLLATE=C + REP=. + + while read KEY + do + NAME=selection_$KEY + zcat listeDOI.txt.gz | grep "$KEY" > ${REP}/$NAME.txt + done < $REP/listeCles.txt + ``` + +
+ + > ⚠ Il est important de noter que, surtout pour le fichier des critères de + > sélection, le traitement se déroule sous Unix/Linux. Par conséquent, il faut + > prendre garde aux fins de ligne qui doivent être de type Unix (`\n`). + > La présence de fins de ligne de type Windows (`\r\n`) perturbe les opérations + > de sélection comme avec `grep` (matching incorrect). + +[Précédent](./commandes.md) - [Suivant](../sed/README.md)