bash
a été initialement conçu à la fin des années 80 comme un clone partiel de ksh
certaines fonctionnalités interactives de csh / tcsh.
Les origines du globbing doivent être trouvées dans les coquilles antérieures sur lesquelles il s'appuie.
ksh
lui-même est une extension du shell Bourne. Le shell Bourne lui-même (sorti pour la première fois en 1979 dans Unix V7) était une implémentation propre à partir de zéro, mais il ne s'écartait pas complètement du shell Thompson (le shell de V1 -> V6) et incorporait des fonctionnalités du shell Mashey.
En particulier, les arguments de commande étaient toujours séparés par des blancs, |
était désormais le nouvel opérateur de canal mais ^
était toujours pris en charge comme alternative (et explique également pourquoi vous le faites [!a-z]
ou non [^a-z]
), $1
était toujours le premier argument d'un script et la barre oblique inverse était toujours le caractère d'échappement. . De nombreux opérateurs regexp ( ^\|$
) ont une signification particulière dans le shell.
La coque Thompson s'appuyait sur un utilitaire externe pour la globulation. Une fois sh
trouvé sans guillemets *
, [
ou ?
s dans la commande, il exécuterait la commande glob
.
rm *.txt
finirait par exécuter glob comme:
["glob", "rm", "*.txt"]
et glob finirait par fonctionner rm
avec la liste des fichiers correspondant à ce modèle.
grep a.\*b *.txt
se déroulerait glob
comme:
["glob", "grep", "a.\252b", "*.txt"]
Ce qui *
précède a été cité en définissant le 8e bit sur ce caractère, empêchant glob
de le traiter comme un caractère générique. glob
retirerait alors ce bit avant d'appeler grep
.
Pour faire l'équivalent avec des expressions régulières, cela aurait été:
regexp rm '\.txt$'
Ou:
regexp rm '^[^.].*\.txt$'
pour exclure les fichiers dot.
La nécessité d'échapper aux opérateurs car ils se doublent de caractères spéciaux shell, le fait que .
, commun aux noms de fichiers, est un opérateur regexp, il n'est pas très approprié de faire correspondre les noms de fichiers et compliqué pour un débutant. Dans la plupart des cas, vous n'avez besoin que de caractères génériques qui peuvent remplacer un ( ?
) ou n'importe quel nombre ( *
) de caractères.
Maintenant, différents shells ont ajouté différents opérateurs de globbing. De nos jours, les globes ksh et zsh (et dans une certaine mesure bash -O extglob
qui implémentent un sous-ensemble de globes ksh) sont fonctionnellement équivalents aux regexps avec une syntaxe moins lourde à utiliser avec les noms de fichiers et la syntaxe shell actuelle. Par exemple, dans zsh
(avec l'extension extendedglob), vous pouvez faire:
echo a#.txt
si vous voulez (peu probable) faire correspondre les noms de fichiers composés de séquences a
suivies de .txt
. Plus echo (^a*\.txt$)
simple que (ici, utiliser des accolades comme moyen d'isoler les opérateurs regex des opérateurs shell qui auraient pu être à sens unique pour les shells).
echo (foo|bar|<1-20>).(#i)mpg
Pour les fichiers mpg (insensibles à la casse) dont le nom de base est foo, bar ou un nombre décimal de 1 à 20 ...
ksh93
peut désormais incorporer des expressions rationnelles (de base, étendues, de type perl ou "augmentées") dans ses globes (bien que ce soit assez bogué) et fournit même un outil pour convertir entre glob et regexp ( printf %R
, printf %P
):
echo ~(Ei:.*\.txt)
à match (non caché) txt fichiers avec E Xtended expressions régulières, crémerie- i nsensitively.
rm -- ^[^.].*\.txt$
place derm -- *.txt
?