# 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`.  

    <details>
      <summary>Voir la solution</summary>

    > ⚠  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
    ```

    </detais>

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.

    <details>
    <summary>Voir la solution</summary>

    ```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
    ```

    </details>

## 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`.

    <details>
    <summary>Voir la solution</summary>

    ```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 "<exodic " | wc -l`

    echo Nombre de notices dans $1: ${NB_NOTICES}
    ```

    </details>

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`.

    <details>
    <summary>Voir la solution</summary>

    ```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 "<exodic " | wc -l`

    echo Nombre de notices dans $1: ${NB_NOTICES} > resultats.txt
    ```

    > ⚠ Cette fois, on a mis la chaîne contenant les apostrophes (caractère
    > spécial) entre guillemets pour les banaliser.

    </details>

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`.

    <details>
    <summary>Voir la solution</summary>

    ```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.
    </details>

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).

    <details>
    <summary>Voir la solution</summary>

    ```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
    ```

    </details>

    > ⚠ 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).
