Liste des entrées dans un répertoire en utilisant grep

J’essaie de lister toutes les entrées dans un répertoire dont les noms contiennent UNIQUEMENT des majuscules. Les répertoires doivent être “/” ajoutés.

#!/bin/bash cd ~/testfiles/ ls | grep -r *.* 

Puisque grep recherche par défaut uniquement les lettres majuscules (non?), Je recherche simplement récursivement les répertoires sous les fichiers de test pour tous les noms ne contenant que des majuscules.

Malheureusement, cela ne fonctionne pas.

En ce qui concerne l’ajout de répertoires, je ne sais pas pourquoi je dois le faire. Est-ce que quelqu’un sait où je peux commencer avec des explications détaillées sur ce que je peux faire avec grep? De plus, comment aborder mon problème?

Non, grep ne considère pas seulement les lettres majuscules.

Votre question est un peu floue, par exemple:

  • d’après votre utilisation de l’option -r, il semble que vous vouliez effectuer une recherche récursive, mais vous ne le dites pas. Pour simplifier, je suppose que vous n’en avez pas besoin; pensez à regarder dans la réponse de @tmm si vous avez besoin de récursivité.
  • vous voulez rechercher uniquement les lettres majuscules. Cela signifie-t-il que vous ne voulez pas accepter d’autres caractères (sans lettre), mais qui sont valides pour les noms de fichiers (comme les chiffres ou les tirets, les points, etc.)?
  • puisque vous ne dites pas que je ne suis pas autorisé à n’avoir que sur fichier par ligne, je suppose que c’est OK (donc en utilisant ls -1 ).

La solution naïve serait:

 ls -1 | grep "^[[:upper:]]\+$" 

Autrement dit, imprimez toutes les lignes ne contenant que des lettres majuscules. Dans mon répertoire TEMP qui imprime, par exemple:

 ALLBIG LCFEM WPDNSE 

Cela exclurait toutefois des fichiers comme README.TXT ou FILE001 , qui selon votre besoin (voir ci-dessus) devraient très probablement être inclus.

Ainsi, une meilleure solution serait:

 ls -1 | grep -v "[[:lower:]]\+" 

Autrement dit, imprimez toutes les lignes ne contenant pas de lettre minuscule. Dans mon répertoire TEMP qui imprime par exemple:

 ALLBIG ALLBIG-01.TXT ALLBIG005.TXT CRX_75DAF8CB7768 LCFEM WPDNSE ~DFA0214428CD719AF6.TMP 

Enfin, pour “marquer correctement” les répertoires avec un “/” --classify , vous pouvez utiliser l’option -F (ou --classify ).

 ls -1F | grep -v "[[:lower:]]\+" 

Encore une fois, exemple de sortie:

 ALLBIG ALLBIG-01.TXT ALLBIG005.TXT CRX_75DAF8CB7768 LCFEM/ WPDNSE/ ~DFA0214428CD719AF6.TMP 

Notez qu’une autre option serait d’utiliser find , si vous pouvez vivre avec les différentes sorties (par exemple find ! -regex ".*[az].*" ), Mais cela aura une sortie différente.

L’expression régulière exacte dépend du format de sortie de votre commande ls. En supposant que vous n’utilisez pas un alias pour ls, vous pouvez essayer ceci:

 ls -R | grep -o -w "[AZ]*" 

notez qu’avec -R dans ls vous listerez récursivement les répertoires et les fichiers dans le répertoire courant. L’option grep -o indique à grep de n’imprimer que la partie correspondante du texte. Les options -w indiquent à grep de ne considérer les correspondances que pour des mots entiers. Le "[AZ]*" est une expression rationnelle pour filtrer uniquement les mots en majuscules.

Notez que cette expression rationnelle imprimera TEST.txt ainsi que TEXT.TXT. En d’autres termes, il ne prendra en compte que les noms formés par des lettres.

C’est ls qui liste les fichiers, pas grep , c’est donc là que vous devez spécifier que vous voulez “/” ajouté aux répertoires. Utilisez ls --classify pour append “/” aux répertoires.

grep est utilisé pour traiter les résultats de ls (ou d’une autre source, en général) et affiche uniquement les lignes correspondant au modèle que vous spécifiez. Il n’est pas limité aux caractères majuscules. Vous pouvez le limiter aux caractères majuscules et “/” avec grep -E '^[AZ/]*$ ou si vous voulez aussi des nombres, des points, etc., vous pouvez filtrer les lignes contenant des caractères minuscules avec grep -v -E [az] .

Comme grep n’est pas le programme qui répertorie les fichiers, ce n’est pas l’endroit où vous souhaitez effectuer la récursivité. ls peut lister les chemins de manière récursive si vous utilisez ls -R . Cependant, vous allez simplement obtenir le dernier composant des chemins de fichiers de cette façon.

Vous pouvez envisager d’utiliser find pour gérer la récursivité. Cela fonctionne pour moi:

find . -exec ls -d --classify {} \; | egrep -v '[az][^/]*/?$'

Je devrais noter que l’utilisation de ls --classify pour append “/” à la fin des répertoires peut également append d’autres caractères à d’autres types de chemins qu’il peut classer. Par exemple, il peut append “*” à la fin des fichiers exécutables. Si cela n’est pas correct, mais que vous êtes d’accord pour lister séparément les répertoires et les autres chemins, vous pouvez contourner ce problème en exécutant find deux fois, une fois pour les répertoires, puis pour d’autres chemins. Cela fonctionne pour moi:

find . -type d | egrep -v '[az][^/]*$' | sed -e 's#$#/#'

find . -not -type d | egrep -v '[az][^/]*$'