1. Outils de base de traitement du texte

1. Redirections et tubes

http://wiki.bash-hackers.org/syntax/redirection

1.1. Redirections >, >>, <, |

  • Les processus UNIX ouvrent trois descripteurs de fichiers standards (correspondant aux flux standards) qui permettent de traiter les entrées et sorties. Ces descripteurs standards peuvent être redéfinis pour chaque processus. Dans la plupart des cas, le descripteur stdin (entrée standard) est le clavier, et les deux descripteurs de sortie, stdout (sortie standard) et stderr (l'erreur standard), sont l'écran.
  • Un processus et ses 3 descripteurs de fichiers STDIN (0), STDOUT (1) et STERR (2)
STDIN < ------ PROCESSUS ---- >
                   |     ---- >> STDOUT
                   |     ---- |
                   |
                   2>
                 STDERR

1.2. Redirection de l'entrée standard

programme < fichier
  • Dans ce cas, les données vont de droite à gauche. L'opérateur "<" ne peut être utilisé qu'avec stdin : on ne peut pas l'utiliser avec les flux de sortie.
  • Si le fichier contient les instructions l et q (une instruction par ligne), alors dans l'exemple suivant fdisk affichera la table des partitions de /dev/sda, puis affichera l'aide puis quittera :
$ cat > fdisk.txt
l
q
[CRTL-D]
$ su
# fdisk /dev/?da < fdisk.txt
# exit
  • Redirection de l'entrée standard :
PROCESSUS ---- < ---- FICHIER / PÉRIPHÉRIQUE
         ---- 0< ----

1.3. Etiquettes

Une étiquette permet de limiter la redirection. C'est utile par exemple pour donner des arguments à une commande sur plusieurs lignes. Un autre usage est la création de fichiers à partir d'un script. Dans l'exemple suivant, on envoie un émail sur plusieurs lignes avec la commande mail.

$ mail mon@adresse <<FIN
> ceci
> est
> un
> test
> FIN

Exercice : Créer des fichiers avec un script bash.

Par exemple un script qui crée un fichier personnalisé :

#!/bin/bash
n=1
touch fichier-$n.txt
cat << EOF > fichier-$n.txt
Ceci est le fichier n°$n
Ligne 2
Ligne 3
Ligne 4
EOF
echo "fichier-$n créé"

1.4. Redirection de la sortie standard

  • Les données vont de gauche à droite.
programme > fichier

Par exemple, avec les droits de root :

fdisk -l /dev/?da > partitions.txt
  • Ceci lance fdisk et redirige la sortie vers le fichier partitions.txt. La sortie n'est pas visible a l'écran. Notez que le shell lit cette commande à partir de la droite : le fichier partitions.txt est d'abord créé s'il n'existait pas auparavant, écrasé dans le cas contraire car l'opérateur ">" est utilisé.
  • L'opérateur ">>" ajoute la sortie standard à un fichier sans l'écraser.
  • Redirection de la sortie standard :
          ---- > ----
PROCESSUS ---- >> ---- FICHIER / PÉRIPHÉRIQUE
          ---- 1> ----

1.5. Exemples de redirection de la sortie standard

  • > crée un nouveau fichier avec la sortie standard
  • >> ajoute la sortie au fichier

Par exemple :

$ date > date.txt
$ cat date.txt
dim fév 21 04:52:01 CET 2016
$ date >> date.txt
$ cat date.txt
dim fév 21 04:52:01 CET 2016
dim fév 21 04:53:09 CET 2016
$ date > date.txt
$ cat date.txt
dim fév 21 04:53:32 CET 2016

1.6. Redirection de la sortie erreur standard

programme 2> fichier_erreur
  • stdin, stdout et stderr sont représentés respectivement par 0, 1 et 2. Cela nous permet de choisir le flux d'erreur standard. Par exemple, vers une corbeille :
ls /fake / 2> /dev/null
  • Par exemple, vers un fichier :

ls /fake 2> err.txt
* Redirection de l'erreur standard :

PROCESSUS ---- 2> ---- FICHIER / PÉRIPHÉRIQUE

1.7. Travailler avec les redirections

  • La commande suivante donne des erreurs et une sortie standard :
$ find /etc/ -name "*.crt"
/etc/ssl/certs/ca-certificates.crt
find: /etc/ssl/private: Permission denied
...

1.8. Isoler et diviser des sorties

  • Isoler la sortie erreur :
$ find /etc/ -name "*.crt" > /dev/null
find: /etc/ssl/private: Permission denied
  • Isoler la sortie standard :
$ find /etc/ -name "*.crt" 2> /dev/null
/etc/ssl/certs/ca-certificates.crt
  • Diviser les sorties :
$ find /etc/ -name "*.crt" 2> /dev/null
/etc/ssl/certs/ca-certificates.crt
$ find /etc/ -name "*.crt" > crt.txt 2> crt.err
$ cat crt.txt
/etc/ssl/certs/ca-certificates.crt
$ cat crt.err
find: /etc/ssl/private: Permission denied
  • Exemple récapitulatif à méditer

Avec le fichier fdisk.txt.

fdisk /dev/?da < fdisk.txt 2> /dev/null > resultat.txt

Le fichier fdisk.txt envoie des commandes en entrée à l'exécutable fdisk, le résultat sans les erreurs est écrit dans le fichier resultat.txt.

1.9. Tubes

programme1 | programme2
  • Les tubes sont représentés par l'opérateur "|". Les données vont de gauche à droite. La figure suivante indique comment la sortie standard du premier processus est redirigée vers l'entrée standard du second processus.
  • Redirection à partir d'un tube :
PROCESSUS1 (stdout) ---- | ---- (stdin) PROCESSUS2
  • Exemple :
$ ps aux | grep login

Note : L'utilitaire pgrep fournit le même résultat.

2. Outils de traitement du texte

2.1. cat : éditeur rudimentaire

La commande cat peut être utilisée comme un éditeur de texte rudimentaire.

$ cat > texte.txt
ligne 1
ligne 2
ligne 3
Crtl+D
  • Vous noterez l'utilisation de Ctrl+D. Cette commande est utilisée pour clore la saisie.

2.2. cat lecteur de texte

On utilise plus couramment cat pour envoyer du texte vers la sortie standard.

Les options les plus courantes sont :

  • -n numéroter chaque ligne de la sortie
  • -b numéroter uniquement les lignes non vides
  • -A afficher le retour charriot

Exemples :

$ cat texte.txt
ligne 1
ligne 2
ligne 3
$ cat -n /etc/resolv.conf

2.3. tac lecteur inverse

tac fait la même chose que cat à l'exception qu'elle lit de la dernière ligne à la première.

$ tac texte.txt
ligne 3
ligne 2
ligne 1

2.4. head et tail

On utilise souvent les commandes head et tail pour analyser les fichiers de journaux. Par défaut, ces commandes affichent 10 lignes. En voici les utilisations les plus courantes :

  • afficher les 20 premières lignes de /var/log/messages :
$ head -n 20 /var/log/messages
$ head -20 /var/log/messages
  • afficher les 20 dernières lignes de /etc/aliases:
tail -20 /etc/aliases

tail a une option supplémentaire qui nous permet d'afficher la fin d'un texte en commençant par une ligne donnée.

  • afficher le texte en partant de la ligne 25 de /var/log/messages
tail -n +25 /var/log/messages

tail peut afficher un fichier en continu avec l'option -f. C'est très pratique pour suivre les modifications d'un fichier en temps réel.

2.5. Commande tee

La commande tee permet à la fois de lire un flux et de le rediriger.

Par exemple, tee donne la sortie et l’écrit dans le fichier ls1.txt :

$ ls | tee ls1.txt

La sortie de la liste de fichiers dont on compte les lignes est redirigée vers la sortie standard et dans le fichier count.txt

ls -l *.txt | wc -l | tee count.txt

3. Manipulation de texte

  • Compter des lignes, des mots, des octets
  • Remplacer des tabulations par des espaces
  • Afficher les fichiers binaires
  • Découper les fichiers
  • Sélectionner les champs et les caractères avec cut
  • Trouver des doublons
  • Trier la sortie
  • Couper des fichiers
  • Jointure de texte
  • Mise en forme de la sortie avec fmt et pr
  • Convertir les caractères

3.1. Compter lignes, mots et octets avec la commande wc

La commande wc compte le nombre d'octets, de mots et de lignes dans les fichiers.

Les options suivantes vous permettent de sélectionner ce qui nous intéresse :

  • -l compte le nombre de lignes
  • -w compte le nombre de mots (words)
  • -c compte le nombre d'octets
  • -m compte le nombre de caractères
  • sans argument, wc compte ce qui est saisi dans stdin.

Par exemple :

$ wc -l /etc/passwd
$ cat /etc/passwd | wc -l

3.2. Remplacer les tabulations par des espaces

  • On utilise la commande expand pour remplacer les tabulations par des espaces.
  • unexpand est utilisé pour l'opération inverse.

3.3. Afficher les fichiers binaires

  • Il y a nombre d'outils pour ça. Les plus courants sont od (octal dump) et hexdump.

3.4. Découper les fichiers avec la commande split

La commande split peut découper un fichier en plusieurs fichiers plus petits à partir de critères comme la taille ou le nombre de lignes. Par exemple, nous pouvons découper /etc/passwd en fichiers de 5 lignes chacun :

$ split -l 5 /etc/passwd
  • Cette commande va créer des fichiers appelés xaa, xab, xac, xad, etc., chaque fichier contenant au plus 5 lignes. Tentez et vérifiez :
$ split -dl 5 /etc/passwd passwd
  • Il est possible de donner un préfixe plus significatif que "x", comme "pass-5" :
$ split -l 5 /etc/passwd passwd-5
  • Cette commande crée des fichiers identiques à la commande précédente, mais ils sont désormais nommés passwd-5aa, passwd-5ab, passwd-5ac, passwd-5ad, ...

3.5. Sélectionner les champs et les caractères avec cut

La commande cut peut extraire une plage de caractères ou de champs de chaque ligne d'un texte.

  • L'option -c est utilisée pour manipuler les caractères.
  • Syntaxe : cut –c {plage1,plage2}

Exemple :

cut -c5-10,15- /etc/passwd
  • Cette commande extrait les caractères 5 à 10 puis 15 jusqu'à la fin pour chaque ligne de /etc/passwd.

  • On peut spécifier le séparateur de champ (espace, virgule, etc.) d'un fichier ainsi que les champs à extraire. Ces options sont définies respectivement par les options -d (delimiter) et -f (field).

Syntaxe :

  • cut -d {séparateur} -f {champs}

  • Exemple :

cut -d: -f 1,7 --output-delimiter=" " /etc/passwd
  • Cette commande extrait les 1er et 7e champs de /etc/passwd séparés par un espace. Le délimiteur de sortie est le même que le délimiteur d'entrée d'origine (par défaut, la tabulation). L'option --output-delimiter vous permet de le changer.

3.6. Trouver des doublons avec la commande uniq

  • Éliminer les lignes successives en doublon
  • La commande uniq n'envoie à STDOUT qu'une version des lignes successives identiques. Par exemple :
$ uniq > /tmp/list1
ligne 1
ligne 2
ligne 2
ligne 3
ligne 3
ligne 3
ligne 1
^D
$ cat /tmp/UNIQUE
sort | uniq > /tmp/UNIQUE

3.7. Trier la sortie avec la commande sort

Par défaut, sort trie le texte par ordre alphabétique. Pour effectuer un tri numérique, utilisez l'option -n.

$ cat > /tmp/list2
ligne 1
ligne 2
ligne 2
ligne 1
ligne 3
ligne 2
ligne 3
ligne 1
$ sort /tmp/list2
$ sort /tmp/list2 | uniq > /tmp/list3

3.8. Jointure de texte avec paste

La commande la plus facile est paste qui "concatène" deux fichiers l'un à la suite de l'autre.

  • Syntaxe :

paste texte1 texte2
* Exemples avec deux fichiers :

texte1 :

01 Paris
02 Luxembourg
03 Berlin
04 Bruxelles
05 Londres

texte2 :

01 France
02 Grand-Duché de Luxembourg
03 Allemagne
04 Belgique
05 Royaume-Uni
$ paste texte1 texte2
01 Paris    01 France
02 Luxembourg   02 Grand-Duché de Luxembourg
03 Berlin   03 Allemagne
04 Bruxelles    04 Belgique
05 Londres  05 Royaume-Uni
$ paste -s texte1 texte2
01 Paris    02 Luxembourg   03 Berlin   04 Bruxelles    05 Londres
01 France   02 Grand-Duché de Luxembourg    03 Allemagne    04 Belgique 05 Royaume-Uni
$ paste -s -d: texte1 texte2
01 Paris:02 Luxembourg:03 Berlin:04 Bruxelles:05 Londres
01 France:02 Grand-Duché de Luxembourg:03 Allemagne:04 Belgique:05 Royaume-Uni
$ paste -d: texte1 texte2
01 Paris:01 France
02 Luxembourg:02 Grand-Duché de Luxembourg
03 Berlin:03 Allemagne
04 Bruxelles:04 Belgique
05 Londres:05 Royaume-Uni

3.9. Jointure de texte avec join

Avec join vous pouvez en plus préciser quels champs vous souhaitez à condition que les fichiers disposent d'un début de ligne commun.

Syntaxe :

join -j1 {champ_no} -j2{champ_no} texte1 texte2

ou

join -1 {champ_no} -2{champ_no} texte1 texte2
  • Le texte n'est envoyé à la sortie que si les champs sélectionnés correspondent.
  • Les comparaisons se font ligne par ligne et le processus s'arrête dès qu'il n'y a pas de correspondance, même s'il y a d'autres correspondances à la fin du fichier.

Par exemple avec les fichiers précédents :

$ join texte1 texte2
01 Paris France
02 Luxembourg Grand-Duché de Luxembourg
03 Berlin Allemagne
04 Bruxelles Belgique
05 Londres Royaume-Uni
  • Exercice optionnel : Regroupez les fichiers séparés précédemment.

3.10. Mise en forme de la sortie avec fmt et pr

Vous pouvez modifier le nombre de caractères par ligne avec fmt. Par défaut fmt joint les lignes et génère des lignes de 75 caractères.

Options de fmt :

  • -w (width) nombre de caractères par ligne
  • -s découpe les lignes longues mais sans les remplir
  • -u sépare chaque mot par une espace et chaque phrase par deux espaces
  • On peut paginer les longs fichiers pour qu'ils correspondent à une taille donnée avec la commande pr. On peut contrôler la longueur des pages (66 lignes par défaut), la largeur (par défaut 72 caractères) ainsi que le nombre de colonnes.
  • Lorsqu'on produit un texte sur plusieurs colonnes, chaque colonne est tronquée uniformément en fonction de la largeur de page spécifiée. Cela veut dire que des caractères sont supprimés à moins d'avoir édité le texte de façon à éviter cela.

3.11. Convertir les caractères avec la commande tr

La commande tr convertit un ensemble de caractères en un autre.

  • convertir les majuscules en minuscules

tr 'A-B' 'a-b' < fichier.txt
* changer de délimiteur dans /etc/passwd

tr ':' ' ' < /etc/passwd
$ join texte1 texte2 | tr ' ' ':'
01:Paris:France
02:Luxembourg:Grand-Duché:de:Luxembourg
03:Berlin:Allemagne
04:Bruxelles:Belgique
05:Londres:Royaume-Uni

Remarque : tr a seulement deux arguments ! Le fichier n'est pas un argument.

Commentaires