Voir le caractère générique dans le nom du fichier

0

Je sais que je peux utiliser un caractère générique pour extraire des fichiers portant les noms d'un format spécifique en bash à l'aide de l'astérisque, comme suit:

$ ls
a01     a02     a03     a04     a05     a06     a07     a08     a09     b01     b02     b03     b04     b05     b06     b07     b08     b09
$ ls a*
a01     a02     a03     a04     a05     a06     a07     a08     a09
$ ls b*
b01     b02     b03     b04     b05     b06     b07     b08     b09

Mais si je voulais faire quelque chose comme déplacer tous les fichiers en commençant par a dans un répertoire appelé aet déplacer tous les fichiers en commençant par b dans un répertoire appelé b, comment pourrais-je le faire avec une seule commande?

Pouvez-vous faire quelque chose comme ça:

$ mv *0* */

Mais en quelque sorte, référence au premier astérisque dans l'argument de déplacement?

utilisateur3052786
la source

Réponses:

0

Une commande, une ligne:

for n in *;do [ -f "$n" ] && case "$n" in a*) mv "$n" a/;; b*) mv "$n" b/;; esac; done

Alternativement, vous pouvez dériver le nom du répertoire à partir du nom de fichier, mais je ne l'ai pas montré initialement, estimant qu'il s'agit d'une ligne plus longue. Par exemple, la déclaration dans la boucle serait (premier essai):

d=$(echo "$n" | sed -e 's/^\(.\).*/\1/'); [ -f "$n" ] && mv "$n" $d/

utiliserait la première lettre du nom de fichier donné pour obtenir le nom du répertoire. Comparer avec

[ -f "$n" ] && case "$n" in a*) mv "$n" a/;; *b) mv "$n" b/;; esac

pour la déclaration de cas. En réalité, pas beaucoup plus longtemps, mais plus difficile à taper à la volée. Parce que bashest mentionné, on peut utiliser sa syntaxe de sous-chaîne ${parameter:offset:length}pour raccourcir cette ligne:

d=${n:0:1}; [ -f "$n" ] && mv "$n" $d/

ou

[ -f "$n" ] && mv "$n" ${n:0:1}/

(Je rappelle ceci comme une extension bash, et ne le trouve pas dans POSIX ).

En ce qui concerne la question sur la réutilisation de jokers: cela concerne apparemment l’ agrandissement du corset . Ceux-ci sont développés avant le point où vous en auriez besoin. Citer la documentation:

Le développement d'accolade est effectué avant toute autre extension, et les caractères spéciaux par rapport à d'autres extensions sont conservés dans le résultat. C'est strictement textuel . Bash ne pas appliquer une interprétation syntaxique au contexte de l'expansion ou le texte entre les accolades. Pour éviter les conflits avec le développement des paramètres, la chaîne '$ {' n'est pas considérée comme éligible pour le développement de l'accolade.

Thomas Dickey
la source
Wow, c'est beaucoup plus compliqué que ce à quoi je m'attendais. Donc, il n'y a pas quelque chose comme des références arrières dans regex?
user3052786
oui / non: pas avec des caractères génériques, mais seulement pour les noms développés. La boucle que j'ai montrée codait en dur les noms et semblait longue - mais traduire le nom ajouterait environ un tiers à la longueur de la ligne, je me suis donc arrêté là. L'exemple s'assure que la source est un fichier, ce qui le rend un peu plus long.
Thomas Dickey
bash a des substitutions qui éviteraient sed- je fais la plupart de mes scripts pour les applications POSIX.
Thomas Dickey