Réponses:
La globalisation des noms de fichiers shell et les expressions régulières utilisent certains des mêmes caractères, et ils ont des objectifs similaires, mais vous avez raison, ils ne sont pas compatibles. La globalisation des noms de fichiers est un système beaucoup moins puissant.
Dans le nom de fichier globbing:
*
signifie "zéro ou plusieurs caractères"
?
signifie "n'importe quel caractère"
Mais dans les expressions rationnelles, vous devez utiliser .*
pour signifier «zéro ou plusieurs caractères», et .
signifie «tout caractère unique». A ?
signifie quelque chose de tout à fait différent dans les expressions rationnelles: zéro ou une instance de l'élément RE précédent.
Crochets ([]
) semblent fonctionner de la même manière dans les deux systèmes sur le système sur lequel je tape ceci, pour les cas simples au moins. Cela inclut des choses comme les classes de caractères POSIX (par exemple [:alpha:]
). Cela dit, si vous avez besoin que vos commandes fonctionnent sur de nombreux types de systèmes différents, je vous déconseille d'utiliser quoi que ce soit au-delà de choses élémentaires comme des listes de caractères (par exemple [abeq]
) et peut-être des plages de caractères (par exemple [a-c]
).
Ces différences signifient que les deux systèmes ne sont directement interchangeables que pour les cas simples. Si vous avez besoin d'une correspondance regex de noms de fichiers, vous devez le faire d'une autre manière. find -regex
est une option. (Notez qu'il y a aussi find -name
, soit dit en passant, qui utilise la syntaxe glob.)
'%'
signifie '*'
.
Répondre à la question exprimée dans le titre original:
Pourquoi les expressions régulières diffèrent-elles de celles utilisées pour filtrer les fichiers?
L'expansion du nom de fichier est antérieure aux expressions régulières, existait déjà avec la plupart des systèmes d'exploitation (caractères génériques / joker) et est beaucoup plus simple et intuitive que cette dernière.
Bien qu'il *.txt
soit facilement compréhensible par les utilisateurs occasionnels, l'analogue .*\.txt
est quelque chose de plus ciblé pour les utilisateurs / programmeurs expérimentés, sans oublier ^.*\.txt$
...
*.txt
n'est pas égal .*\.txt
, il est (la plupart du temps) égal .*\.txt$
car il ne peut rien y avoir après .txt
(en supposant au moins un remplacement de nom de fichier raisonnable ). Peut-être même ^.*\.txt$
quelque peu en fonction de l'utilisation. Prouve votre point?