Bash : sélection de fichiers par extension

Anne bash makefile latex

Le titre n’est pas terrible, mais le problème était d’effacer de manière élégante les fichiers temporaires générés par LaTeX dans la cible clean d’un Makefile.

La première idée a été d'écrire:

$ rm -f doc.(aux|log|out|toc)

qui bien sûr ne marche pas. En fait, bash ne comprend pas ce genre d’expression régulière.

Plus de motifs pour l’interpréteur bash

En regardant dans la doc, on a un peu plus d’information, et on voit qu’une certaine forme de | est comprise, à condition de positionner l’option extglob qui ne l’est pas par défaut. On peut alors utiliser :

?(pattern-list)
    Matches zero or one occurrence of the given patterns.
*(pattern-list)
    Matches zero or more occurrences of the given patterns.
+(pattern-list)
    Matches one or more occurrences of the given patterns.
@(pattern-list)
    Matches one of the given patterns.
!(pattern-list)
    Matches anything except one of the given patterns.

Pour voir la valeur de l’option, il suffit de faire :

$ shopt extglob

Et pour la positionner si besoin :

$ shopt -s extglob

Intégration dans le Makefile

On serait donc tenté d'écrire dans la règle du Makefile :

shopt -s extglob ; rm -f doc.@(aux|log|out|toc)

Mais ce ne fonctionne toujours pas, car pour prendre effet, l’option doit être positionnée avant l’interprétation de la commande. Or dans un Makefile, chaque ligne de commande est exécutée dans un shell différent. Mais il existe néanmoins une solution, c’est de faire:

bash -O extglob -c "rm -f doc.@(aux|log|out|toc)"

Et cette fois, ça marche !

Autres solutions

Il faut noter d’une alternative serait d’utiliser find :

$ find . -type f -regextype egrep -regex 'doc.(aux|log|out|toc)' -delete

ou bien encore ls et egrep :

$ ls | egrep 'doc.(aux|log|out|toc)' | xargs rm

Voir aussi :