Outils pour utilisateurs

Outils du site


cours:informatique:fun_mooc:maitrise_du_bash_univ-reunion:330_filtres_complexes

Bash: construire des filtres élaborés

Certains programmes utilitaires possède beaucoup d'options permettant d'ajuster finement leurs traitements.

Rechercher/traiter dans le système de fichier

find

La commande find permet de rechercher des fichiers en fonction de nombreux critères. On pourra citer notamment:

  • -name ou -iname pour spécifier les nom ou motifs a trouver
  • -perm pour spécifier des permissions
  • -size pour donner des critères de taille
  • -mtime pour apporter des critère de date de dernière modification.
  • etc

Quelques exemples de recherche sont présentées ci dessous.

# Rechercher dans les répertoires /etc et /bin
# tous les fichiers ou dossiers dont le nom commence par a
find /etc /bin -name "a*"
 
# NB: Les guillemets sont nécessaires pour inhiber
# le développement des noms de fichiers par le shell.
# Le motif doit être transmis sans interprétation à la commande find.
 
Rechercher à partir du répertoire courant tous les fichiers
dont la taille est supérieure a 1 Gio
find . -size +1M
 
#Retrouver à partir du répertoire courant tous les fichiers dont
#la taille est comprise entre 15 Mio et 1 Gio
find . -size +15M -size -1G
 
# Retrouver les fichiers sources avec les suffixes .py ou .cpp
find . -type f -name "*.py" -o "*.cpp"

La commande find permet de lancer des traitements sur les objets retrouvés grâce à l'option -exec. Cette option a une syntaxe particulière. Après l'option on indique la commande a exécuter. Au sein de cette commande, on fait référence à l'objet retrouvé par find avec la syntaxe {}. La commande se termine par le caractère ';' mais comme ce métacaractère est aussi le caractère de séparateur de commande pour le shell il doit être inhibibé.

Il est possible d'appeler plusieurs fois l'option -exec

Ci dessous un exemple d'utilisation de l'option -exec:

# Retrouver à partir du répertoire courant tous les fichiers avec 
# des suffixe .txt. Pour chaque résultat compter le nombre de ligne
# puis copier le fichier dans un fichier de meme nom avec ajout d'un
# suffixe .bak
find . -type f -iname "*.txt" -exec wc -l {} ’;’ -exec cp {} {}.bak ’;’

Rechercher/traiter dans un fichier

grep

La commande grep permet de rechercher des motifs à l’intérieur de fichiers texte.

Parmi les options usuelles on retrouve:

  • -v pour inverser la sélection;
  • -n pour afficher le numéro de ligne;
  • -c pour donner le nombre de lignes trouvées.
  • -i pour retirer la sensibilité à la casse de caractère.
# Retrouver toutes les lignes ne contenant pas UNIX
# dans le fichier slogan.TXT et préfixer le résultat avec
# le numéro des lignes 
$ grep -vn UNIX slogan.txt

La commande grep permet également de décrire des motifs complexes à l'aide des expressions rationnelles (regex)

grep peut également fournir le contexte autour du motif recherché grâce aux options:

  • -B(Before) pour afficher le résultat accompagné d'un certain nombre de lignes précédentes
  • -A(After) retourne le résultat et des lignes aprés
  • -C (Center) retourne le résultat entouré de n lignes avant et après.

awk

awk n’est pas à proprement parler une commande ou un filtre mais plutôt un langage de programmation intégrant la gestion des variables, le calcul arithmétique, les tests logiques et contenant de nombreuses fonctions. awk peut s'utiliser comme un outil de sélection et de manipulation de texte. La syntaxe d’utilisation de la commande awk se présente sous la forme suivante:

$ awk ’commandes awk’ fichier

awk traite les lignes du fichier une à une et de manière séquentielle. Dans awk, chaque ligne contient un certain nombre de champs séparés par un séparateur qui par défaut est une espace. Ce séparateur peut être modifié avec l’option -F de awk, ou encore en changeant la valeur de la variable FS interne à awk.

Les variables apparaissant dans les commandes awk sont locales. Pour awk une ligne complète,est contenue dans la variable $0 et ses différents champs sont $1, $2, $3, … numérotés de gauche à droite.

# awk réécrit sur la sortie standard le fichier wcs.txt
# en modifiant l'ordre des champs
$ awk{print $2 " " $1 " " $3 " " $4}’ wcs.txt

awk traite le ou les fichiers ligne par ligne, mais pas seulement. awk permet aussi de spécifier des blocs de pré-traitement et post-traitement. Ces blocs sont exécutés avant le traitement de la première ligne du ou des fichiers, et après le traitement de la dernière ligne. Pour cela, la syntaxe de awk à utiliser est la suivante (un bloc vide peut être omis):

awk ’ BEGIN { traitements débuts, avant lecture fichier}
{ traitement courants, ligne par ligne}
END
{traitements fins, après parcours fichier} ’ fichier

sed

La commande sed1) est un éditeur de texte non-interactif permettant d’éditer le contenu du fichier de façon automatisée. C’est en fait un filtre, dans sa version basique, qui reçoit un flux de textes sur son entrée standard et produit le résultat sur sa sortie standard. La commande sed peut traiter un un flux de données de taille illimitée en utilisant très peu de mémoire. La commande sed est de ce fait un outil très rapide pour l’édition complexe de fichier.

sed peut utiliser les expressions régulières. La commande sed lit les fichiers dont les noms sont indiqués en argument. Si aucun nom n’est indiqué, elle lit l’entrée standard. On lui indique les traitements à effectuer en utilisant l’option -e (la présence de cette option est facultative s’il n’y a qu’une seule directive de traitement). Par défaut les fichiers indiqués ne sont pas modifiés et le résultat de la transformation est écrit sur la sortie standard. Mais avec l’option -i on peut obtenir que le résultat soit écrit dans chacun des fichiers intitiaux.

L’utilisation principale de la commande sed est l’opération de substitution de chaînes de caractères identifiées par une expression régulière. La forme syntaxique pour exprimer ce traitement est la sui- vante:

s/expression-reguliere/chaine/g
  • s pour substitute
  • g permet de répéter plusieurs fois le traitement sur la même ligne.
cat fichier | sed -e ’s/a/A/g’ -e ’s/TA/ta/g’

Exemples usuels:

# Limiter la substitution aux lignes 1 à 5
$ sed1,5s/UNIX/*nix/g’ slogan.txt
 
# Limiter la substitution aux lignes commencant par C
$ sed -e/^C/s/Bash/BASH/g’ slogan.txt
 
# Limiter la substitution aux lignes contenant le mot clé
# 'that'
$ sed -e/that/s/Bash/BASH/g’ slogan.txt
 
# supprimer (/d) directement dans le fichier passé en paramètre
# les lignes commencant par L et terminant par e
$ sed -i ’’ -e/^L*e$/d’ slogan.txt

Pour préfixer chaque ligne par une chaîne de caractères:

$ cat file | sed -e ’s/.*/Mon prefixe: &/

Ici le motif regex .* permet de selectionner toutes les lignes avec au moins 1 caractère. Le caractère & utilisé dans la substitution permet de référencer la chaîne de caractère trouvée.

La commande sed permet de déclarer des régions et de les réutiliser. Prenons le fichier date.txt suivant:

$ cat date.txt
2017-01-21
2019-11-09
2012-08-17
2003-15-13

Nous pouvons utiliser des régions en utilisant des parenthèses. Ainsi prenons la commande suivante dans laquelle les régions sont définies par les parenthèses (.*)-(.*)-(.*) (avec les caractère d’échappement). Chaque région est séparée par un tiret - comme dans le fichier date.txt. Une fois les régions définies, celles-ci peuvent être utilisées car un numéro leur est affecté. L’exemple suivant montre la transformation du fichier:

$ sed -e ’s/\(.*\)-\(.*\)-\(.*\)/date: \3 \2 \1/’ date.txt
date: 21 01 2017
date: 09 11 2019
date: 17 08 2012
date: 13 15 2003

Quiz

Parmi les propositions, identifiez à quelle action la commande find s'applique:

  • Elle s'applique à la recherche de fichiers dans un ou plusieurs répertoires.

Quelle est la commande pour trouver tous les fichiers ou dossiers se terminant par .txt (sans tenir compte de la casse) situés dans l'arborescence du répertoire courant?

find . -iname "*.txt"

Comment la commande sed fonctionne-t-elle sur un fichier?

  • Elle édite le fichier sans l'afficher à l'écran.

Indiquez pour chaque cible la commande à considérer.

  1. Trouver un fichier dans un répertoire:
    • find
  2. Changer un caractère par un autre caractère dans un fichier:
    • sed
  3. Afficher une ligne d'un fichier en fonction d'une chaîne de recherche:
    • grep
1)
stream editor
cours/informatique/fun_mooc/maitrise_du_bash_univ-reunion/330_filtres_complexes.txt · Dernière modification : 2021/04/01 20:09 de yoann