GNU/Linux >> Tutoriels Linux >  >> Linux

Problème(s) d'expression régulière dans Bash :[^negate] ne semble pas fonctionner

Êtes-vous sûr que ce que vous voulez se passe ?Lorsque vous exécutez ls /directory | grep '[^term]' vous cherchez essentiellement pas les lettres t e r m. Cela signifie que si un fichier a d'autres lettres dans son nom, il apparaîtra toujours dans la sortie de ls . Prenez par exemple le répertoire suivant :

$ ls
alpha  brave  bravo  charlie  delta

Maintenant, si je lance ls |grep '^[brav]' J'obtiens ceci :

$ ls |grep '^[brav]'
alpha
brave
bravo

Comme vous pouvez le voir, non seulement j'ai obtenu brave et bravo J'ai aussi reçu alpha car la classe de caractères [] recevra n'importe quelle lettre de cette liste.

Par conséquent, si je lance ls |grep '[^brav]' J'obtiendrai tous les fichiers qui ne contiennent pas les caractères b r a v n'importe où dans le nom.

$ ls |grep '[^brav]'
alpha
bravo
brave
charlie
delta

Si vous remarquez qu'il incluait la liste complète des répertoires, car tous les fichiers en avaient au moins un lettre qui n'était pas incluse dans la classe de caractères.

Donc, comme l'a dit Kanvuanza, grep pour l'inverse de "terme" par opposition aux caractères t e r m vous devriez le faire en utilisant grep -v .

Par exemple :

$ ls |grep -v 'brav'
alpha
charlie
delta

Aussi, si vous ne voulez pas que les fichiers contiennent des caractères dans la classe, utilisez grep -v '[term]' . Cela empêchera l'affichage de tous les fichiers contenant l'un de ces caractères. (Réponse de Kanvuanza)

Par exemple :

$ ls |grep -v '[brav]'

Comme vous pouvez le voir, aucun fichier n'était répertorié car tous les fichiers de ce répertoire comprenaient au moins une lettre de cette classe.

Avenant :

Je voulais ajouter qu'en utilisant PCRE, il est possible d'utiliser uniquement regex pour filtrer à l'aide d'expressions négatives. Pour ce faire, vous utiliseriez quelque chose connu sous le nom d'expression régulière d'anticipation négative :(?!<regex>) .

Donc, en utilisant l'exemple ci-dessus, vous pouvez faire quelque chose comme ça pour obtenir les résultats que vous voulez sans utiliser grep drapeaux.

$ ls | grep -P '^(?!brav)'
alpha
charlie
delta

Pour déconstruire cette expression régulière, elle correspond d'abord au début d'une ligne ^ puis recherche les chaînes qui ne correspondent pas à brav à suivre ensuite. Seulement alpha , charlie , et delta correspondent donc ce sont les seuls qui sont imprimés.


Je suppose que grep -v drapeau fait ce que vous voulez. À partir de la page de manuel :

-v, --invert-match
    Invert the sense of matching, to select non-matching lines.

Vous pouvez utiliser ls /directory | grep -v [term] pour imprimer les lignes non correspondantes.


Linux
  1. La définition d'une expression régulière ?

  2. LD_LIBRARY_PATH ne semble pas fonctionner

  3. Pourquoi `\d` ne fonctionne-t-il pas dans les expressions régulières de sed ?

  4. chmod ne fonctionne pas

  5. grep extraire la plage de numéros

Expression de séquence bash (plage)

Expressions régulières dans Grep (Regex)

Lors de l'installation de la chaîne d'outils Rust dans Docker, la commande Bash `source` ne fonctionne pas

Pourquoi Bash `(())` ne fonctionne-t-il pas dans `[[]]` ?

Expression régulière pour trouver des caractères doubles dans Bash

Expression régulière avec sed