Disons que je veux copier le contenu d'un répertoire excluant les fichiers et les dossiers dont le nom contient le mot "Musique".
cp [exclude-matches] *Music* /target_directory
Que doit-on mettre à la place de [exclude-matches] pour y parvenir ?
Disons que je veux copier le contenu d'un répertoire excluant les fichiers et les dossiers dont le nom contient le mot "Musique".
cp [exclude-matches] *Music* /target_directory
Que doit-on mettre à la place de [exclude-matches] pour y parvenir ?
En Bash, vous pouvez le faire en activant la fonction extglob
comme ceci (remplacer ls
avec cp
et ajouter le répertoire cible, bien sûr)
~/foobar> shopt extglob
extglob off
~/foobar> ls
abar afoo bbar bfoo
~/foobar> ls !(b*)
-bash: !: event not found
~/foobar> shopt -s extglob # Enables extglob
~/foobar> ls !(b*)
abar afoo
~/foobar> ls !(a*)
bbar bfoo
~/foobar> ls !(*foo)
abar bbar
Vous pouvez par la suite désactiver extglob avec
shopt -u extglob
Le site extglob
L'option de l'interpréteur de commandes vous permet d'obtenir un filtrage plus puissant dans la ligne de commande.
Vous l'activez avec shopt -s extglob
et l'éteindre avec shopt -u extglob
.
Dans votre exemple, vous feriez initialement :
$ shopt -s extglob
$ cp !(*Music*) /target_directory
L'intégralité de l'offre ext terminé globe terrestre bing opérateurs sont (extrait de man bash
) :
Si l'option extglob de l'interpréteur de commandes est activée à l'aide de l'option intégrée shopt, plusieurs opérateurs étendus de recherche de motifs sont reconnus. sont reconnus. Une liste de motifs est une liste d'un ou plusieurs motifs séparés par un |. Les motifs composites peuvent être formés en utilisant un ou plusieurs des sous-motifs suivants :
- ?(liste de motifs)
Correspond à zéro ou une occurrence des motifs donnés- *(liste de motifs)
Correspond à zéro ou plusieurs occurrences des motifs donnés- +(liste de motifs)
Correspond à une ou plusieurs occurrences des motifs donnés- @(liste de motifs)
Correspond à l'un des modèles donnés- !(liste de motifs)
Correspond à tout sauf à l'un des motifs donnés
Donc, par exemple, si vous voulez lister tous les fichiers du répertoire courant qui ne sont pas .c
ou .h
des fichiers, vous le feriez :
$ ls -d !(*@(.c|.h))
Bien sûr, le globing normal de l'interpréteur de commandes fonctionne, donc le dernier exemple pourrait aussi être écrit comme suit :
$ ls -d !(*.[ch])
Par défaut, ls mettra plusieurs fichiers par ligne, ce qui ne donnera probablement pas les bons résultats.
Seulement lorsque stdout est un terminal. Lorsqu'il est utilisé dans un pipeline, ls imprime un nom de fichier par ligne.
Ls ne met plusieurs fichiers par ligne que si la sortie se fait dans un terminal. Essayez vous-même - "ls | less" n'aura jamais plusieurs fichiers par ligne.
Si vous voulez éviter le coût en mémoire de l'utilisation de la commande exec, je pense que vous pouvez faire mieux avec xargs. Je pense que ce qui suit est une alternative plus efficace à
find foo -type f ! -name '*Music*' -exec cp {} bar \; # new proc for each exec
find . -maxdepth 1 -name '*Music*' -prune -o -print0 | xargs -0 -i cp {} dest/
Cela fait une recherche récursive, ce qui est un comportement différent de ce que le PO veut.
J'ai trouvé que c'était la solution la plus propre sans avoir à activer / désactiver les options du shell. L'option -maxdepth serait recommandée dans ce post pour obtenir le résultat souhaité par le PO, mais tout dépend de ce que vous essayez d'accomplir.
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.