Comment trouver tous les fichiers sauf un fichier spécifié

13

Le lspeut donner un résultat comme

[root@localhost ~]# cd /etc/yum.repos.d/
[root@localhost yum.repos.d]# ls

CentOS-Base.repo CentOS-Debuginfo.repo CentOS-Media.repo CentOS-Vault.repo

Mais en fait, j'espère juste découvrir CentOS-Base.repoCentOS-Debuginfo.repoet CentOS-Vault.reponon CentOS-Media.repo. Je lance donc cette commande

ls [^\(Media\)]

Mais je reçois une information d'erreur, comment faire?

Yo de
la source
Connexe: Exclure un motif du match de glob
Steeldriver
@steeldriver Merci pour votre lien, qui m'est très utile ..
yode
Vous pourriez envisager de passer votre shell zsh , qui a une suppression de motif installation
Basile STARYNKEVITCH

Réponses:

10

Dans le cas le plus simple, vous pouvez utiliser ce qui suit (dans le cas où le 1er sous-mot est statique CentOS):

ls CentOS-[BDV]*

  • [BDV] - classe de caractères pour garantir le deuxième sous-mot commençant par l'un des caractères spécifiés

ou même avec négation :

ls CentOS-[^M]*

Si vous voulez ignorer tous les noms de fichiers qui contiennent le Mcaractère, avec l'implémentation GNU de ls(comme on le trouve généralement sur CentOS), utilisez l' option -I( --ignore):

ls -I '*M*'

-I, --ignore = PATTERN
ne répertorie pas les entrées implicites correspondant au shell PATTERN

Pour ignorer les entrées contenant un Mediamot:

ls -I '*Media*'

Ces modèles doivent être transmis textuellement à ls, donc doivent être cités (sinon, le shell les traiterait comme des globes à développer).

RomanPerekhrest
la source
Pourquoi nous ne pouvons pas utiliser ls *[^M]*
yode
Le ls CentOS-[^M]*travail, mais ls *[^M]*pas ..
yode
@yode, cela dépend exactement de ce que vous voulez ignorer: Moccurrence de caractère OU Mediamot?
RomanPerekhrest
Mais dans mon cas, seul ce fichier a un caractère M.
il y a
3
Les modèles sont gourmands: le premier * correspond à tout sauf la dernière lettre, le [^ M] correspond à la dernière lettre car aucun ne se termine par M et le dernier * correspond à la chaîne vide. Ils correspondent donc tous. Et même si quelque chose se terminait par M, cela correspondrait toujours, en supposant qu'il y avait quelque chose de différent de M quelque part: par exemple, si vous aviez un fichier appelé OOM, la première étoile correspondrait au premier O, le [^ M] correspondrait au deuxième O et le départ arrière correspondrait au M.
NickD
12

Quelques coquilles ont des opérateurs de globalisation de négation:

  • zsh -o extendedglob:

    ls -d -- ^*Media*
    ls -d -- *.repo~*Media* # ~ is "except" operator
    
  • ksh, zsh -o kshglob, bash -O extglob:

    ls -d -- !(*Media*)
    
  • bash:

    GLOBIGNORE='*Media*'
    ls -d -- *
    
  • ksh:

    FIGNORE='@(*Media|.)*'
    ls -d -- *
    
Stéphane Chazelas
la source
6

Une option consiste à utiliser findavec les -not -name drapeaux. C'est à dire find . -not -name CentOS-Media.repo. Si vous ne voulez pas récapituler la structure du répertoire, ajoutez un -maxdepth 1indicateur.

Alternativement, on peut écrire ce qui suit (ce qui est beaucoup plus complexe, mais j'ai oublié le -notdrapeau et publié cette réponse à l'origine, donc je ne supprimerai pas cette partie):

find . -print0 | grep --invert-match -z "CentOS-Media.repo$" | tr '\0' '\n'

Vous devez forcer la findséparation des noms de fichiers avec un octet nul, afin que les sauts de ligne dans les noms de fichiers ne décomposent rien. Avec un peu de chance, grepprend en charge ce type de séparateur avec indicateur -z. Vous voudrez peut-être revenir à la séparation typique (c.-à-d. Octet nul -> nouvelle ligne) avectr '\0' '\n'

mouche en polystyrène
la source
1
Vous pouvez également obtenir des noms de fichiers séparés printf '%s\0' *par des valeurs nulles qui ne récurrent pas et n'incluent pas de fichiers dot par défaut (mais certains shells ont une option pour cela). Vous n'avez pas non plus besoin -Ede cette expression rationnelle, mais pour être pointilleux, vous devez soit la barre oblique inverse, soit la .mettre [], et vous dépendez de GNU find et grep.
dave_thompson_085
4

La façon la plus simple est d'utiliser find. Faire:

find . -maxdepth 1 -type f ! -name "CentOS-Media.repo"

Ici, "f" signifie rechercher des fichiers normaux uniquement (exclut cependant les liens symboliques vers des fichiers normaux; avec GNU find, utilisez -xtype fplutôt pour les inclure). Si vous souhaitez rechercher des répertoires, passez plutôt "d".

( -maxdepthalors qu'au départ une extension GNU est maintenant assez courante. Si votre findne la prend pas en charge, vous pouvez la remplacer -maxdepth 1par la norme ! -name . -prune).

voir la page de manuel find pour plus de fonctionnalités impressionnantes.

Al 123
la source