Répertorier les fichiers qui correspondent à un modèle mais ignorer les fichiers qui correspondent à un autre modèle?

12

Disons que j'ai un répertoire avec les fichiers a1, a2, a3, b1, b2, b3. Je veux seulement faire correspondre les fichiers commençant par amais ne contenant pas 3. J'ai essayé ls -I "*3" *a*mais ça revient a1 a2 a3, même si je ne veux pas qu'elle corresponde a3. Est-ce possible avec ls?

Steven
la source
un ensemble diversifié intéressant de réponses ici, mais une explication de la raison pour laquelle ls -I '* 3' a * échoue serait édifiante. et / ou pourquoi la liste globbed du shell n'est-elle pas par la suite filtrée par le commutateur ignore sur ls?
Theophrastus
La page de manuel dit à propos de l'option -I: do not list implied entries matching shell PATTERNcependant, elle n'explique pas ce que l'on entend par implicite , mais je suppose qu'elle ne s'applique qu'aux fichiers qui lssont obtenus par des extensions globales - et lsne développe pas le a*, le shell le fait .
Murray Jensen

Réponses:

14

Juste:

shopt -s extglob  
ls a!(*3*)
  • shopt -s extglob active la globalisation étendue.
  • a correspond au début a
  • !()annule le match à l'intérieur du ()...
    • *3*qui est 3et n'importe quoi avant ou après.

$ touch 1 2 3 a1 a2 a3 b1 b2 b3 aa1 aa2 aa3 a2a a3a
$ ls a!(*3*)
a1  a2  a2a  aa1  aa2
le chaos
la source
1
Pour info, nécessiteset -s extglob
Brian
@Brian Yea, juste remarqué ^^
chaos
8

Les réponses existantes indiquent bien la meilleure façon de le faire avec des globes; J'inclurai cela parce que dans la plupart des cas, findc'est une meilleure option si vous voulez faire du script ou un traitement supplémentaire:

$ find . -maxdepth 1 -name 'a*' -not -name '*3*'
./a1
./a2

Vous pouvez alimenter la réponse xargspour des actions faciles ou une while readboucle pour des choses plus compliquées.

Tom Hunt
la source
4

Un moyen simple est

  • pour répertorier tous les fichiers qui correspondent a*
  • puis supprimez toutes les lignes contenant un 3

La commande UNIX est

ls -1 a* | grep -v 3

ls -1 affiche un fichier par ligne.

greptrouve normalement des lignes qui correspondent à un modèle mais avec -vce comportement est inversé, ie grep trouve une ligne qui ne correspond pas à ce modèle.

Peter K
la source
2
Salut Peter! Il serait préférable d'expliquer, avec autant de détails que possible, le fonctionnement de votre solution.
dhag
2
L'analyse lsn'est pas une idée de goob: mywiki.wooledge.org/ParsingLs
chaos
3

Avec zsh, en utilisant l' ~ opérateur glob :

setopt extendedglob
print -rl -- a*~*3*

Avec gnu lsvous pouvez utiliser deux --ignoreoptions:

ls -I '[^a]*' -I '*3*'

le 1er ignore tous les noms de fichiers qui ne commencent pas par aet le 2e ignore les noms de fichiers qui contiennent3

don_crissti
la source