Question Répertorier uniquement les répertoires utilisant ls dans bash: un examen


Cette commande répertorie les répertoires dans le chemin actuel: ls -d */

Que fait exactement le motif */ faire?

Et comment pouvons-nous donner le chemin absolu dans la commande ci-dessus (par ex. ls -d /home/alice/Documents) pour répertorier uniquement les répertoires dans ce chemin?


702
2018-01-16 06:07


origine


Réponses:


*/ est un modèle qui correspond à tous les sous-répertoires du répertoire en cours (* correspondrait à tous les fichiers et sous-répertoires; la / le restreint aux répertoires). De même, pour lister tous les sous-répertoires sous / home / alice / Documents, utilisez ls -d /home/alice/Documents/*/


743
2018-01-16 06:11



Quatre façons d'y parvenir, chacune avec un format de sortie différent

1. Utilisation echo

Exemple: echo */, echo */*/
Voici ce que j'ai:

cs/ draft/ files/ hacks/ masters/ static/  
cs/code/ files/images/ static/images/ static/stylesheets/  

2. Utilisation ls seulement

Exemple: ls -d */
Voici exactement ce que j'ai:

cs/     files/      masters/  
draft/  hacks/      static/  

Ou comme liste (avec des informations détaillées): ls -dl */ 

3. Utilisation ls et grep

Exemple: ls -l | grep "^d" Voici ce que j'ai:

drwxr-xr-x  24 h  staff     816 Jun  8 10:55 cs  
drwxr-xr-x   6 h  staff     204 Jun  8 10:55 draft  
drwxr-xr-x   9 h  staff     306 Jun  8 10:55 files  
drwxr-xr-x   2 h  staff      68 Jun  9 13:19 hacks  
drwxr-xr-x   6 h  staff     204 Jun  8 10:55 masters  
drwxr-xr-x   4 h  staff     136 Jun  8 10:55 static  

4. Script Bash (non recommandé pour le nom de fichier contenant de l'espace.)

Exemple: for i in $(ls -d */); do echo ${i%%/}; done
Voici ce que j'ai:

cs  
draft  
files  
hacks  
masters  
static

Si vous aimez avoir '/' comme caractère de fin, la commande sera: for i in $(ls -d */); do echo ${i}; done

cs/  
draft/  
files/  
hacks/  
masters/  
static/

379
2018-06-09 12:21



J'utilise:

ls -d */ | cut -f1 -d'/'

Cela crée une seule colonne sans barre oblique finale - utile dans les scripts.

Mes deux centimes.


74
2018-02-27 15:19



Pour tous les dossiers sans pour autant sous-dossiers:

find /home/alice/Documents -maxdepth 1 -type d

Pour tous les dossiers avec sous-dossiers:

find /home/alice/Documents -type d

40
2017-07-23 08:30



4 (plus) Options fiables.

Un non cité astérisque * sera interprété comme un motif (glob) par le shell.
Le shell l'utilisera dans l'extension du chemin.
 Il va ensuite générer une liste de noms de fichiers qui correspondent au modèle.
 Un astérisque simple correspondra à tous les noms de fichiers dans le PWD (répertoire de travail actuel).
Un modèle plus complexe que */ va correspondre à tous les noms de fichiers qui se terminent par /.
 Ainsi, tous les répertoires. C'est pourquoi la commande:

1.- écho.

echo */
echo ./*/              ### avoid misinterpreting filenames like "-e dir"

sera étendu (par le shell) à echo tous les répertoires dans le PWD.


Pour tester ceci: Créez un répertoire (mkdir) nommé comme test-dir, et cd dans ça:

mkdir test-dir; cd test-dir

Créer des répertoires:

mkdir {cs,files,masters,draft,static}   # safe directories.
mkdir {*,-,--,-v\ var,-h,-n,dir\ with\ spaces}  # some a bit less secure.
touch -- 'file with spaces' '-a' '-l' 'filename'    # and some files:

La commande echo ./*/ restera fiable même avec des fichiers nommés impairs:

./--/ ./-/ ./*/ ./cs/ ./dir with spaces/ ./draft/ ./files/ ./-h/
./masters/ ./-n/ ./static/ ./-v var/

Mais les espaces dans les noms de fichiers rendent la lecture un peu confuse.


Si au lieu de echo, nous utilisons ls, le shell est toujours ce qui étend la liste des noms de fichiers. Le shell est la raison pour obtenir une liste de répertoires dans le PWD. le -d option à ls fait qu'il liste l'entrée du répertoire actuel au lieu du contenu de chaque répertoire (comme présenté par défaut).

ls -d */

Cependant, cette commande est (un peu) moins fiable. Il échouera avec les fichiers nommés impairs énumérés ci-dessus. Il va s'étouffer avec plusieurs noms. Vous devez effacer un par un jusqu'à ce que vous trouviez ceux qui ont des problèmes.

2.- ls

Le GNU ls acceptera la "fin des options" (--) clé.

ls -d ./*/                     ### more reliable BSD ls
ls -d -- */                    ### more reliable GNU ls

3.-printf

Pour répertorier chaque répertoire dans sa propre ligne (dans une colonne, similaire à ls -1), utilisez:

$ printf "%s\n" */        ### Correct even with "-", spaces or newlines.

Et, encore mieux, nous pourrions supprimer le suivi /:

$ set -- */; printf "%s\n" "${@%/}"        ### Correct with spaces and newlines.

Une tentative comme ceci:

$ for i in $(ls -d */); do echo ${i%%/}; done

Va échouer sur:

  • quelques noms (ls -d */) comme déjà indiqué ci-dessus.
  • sera affectée par la valeur de IFS.
  • divisera les noms sur les espaces et les onglets (par défaut IFS).
  • chaque nouvelle ligne dans le nom commencera une nouvelle commande d'écho.

4.- Fonction

Enfin, l'utilisation de la liste d'arguments dans une fonction n'affecte pas la liste des arguments du shell en cours d'exécution. Simplement:

$ listdirs(){ set -- */; printf "%s\n" "${@%/}"; }
$ listdirs

présente cette liste:

--
-
*
cs
dir with spaces
draft
files
-h
masters
-n
static
-v var

Ces options sont sécurisées avec plusieurs types de noms de fichiers impairs.


28
2017-07-24 06:02



le tree commande est également très utile ici. Par défaut, il affichera tous les fichiers et répertoires à une profondeur complète, avec des caractères ASCII montrant l'arborescence.

$ tree
.
├── config.dat
├── data
│   ├── data1.bin
│   ├── data2.inf
│   └── sql
|   │   └── data3.sql
├── images
│   ├── background.jpg
│   ├── icon.gif
│   └── logo.jpg
├── program.exe
└── readme.txt

Mais si nous voulions obtenir seulement les répertoires, sans l'arbre ascii, et avec le chemin complet depuis le répertoire courant, vous pourriez faire:

$ tree -dfi
.
./data
./data/sql
./images

Les arguments étant:

-d     List directories only.
-f     Prints the full path prefix for each file.
-i     Makes tree not print the indentation lines, useful when used in conjunction with the -f option.

Et si vous voulez le chemin absolu, vous pouvez commencer en spécifiant le chemin complet du répertoire courant:

$ tree -dfi "$(pwd)"
/home/alice/Documents
/home/alice/Documents/data
/home/alice/Documents/data/sql
/home/alice/Documents/images

Et pour limiter le nombre de sous-répertoires, vous pouvez définir le niveau maximal de sous-répertoires avec -L level, par exemple:

$ tree -dfi -L 1 "$(pwd)"
/home/alice/Documents
/home/alice/Documents/data
/home/alice/Documents/images

Plus d'arguments peuvent être vus avec arbre de l'homme


13
2018-06-16 15:30



Au cas où vous vous demandez pourquoi la sortie de 'ls -d * /' vous donne deux slashes traînants, comme:

[prompt]$ ls -d */    
app//  cgi-bin//  lib//        pub//

C'est probablement parce que quelque part votre shell ou session config fichiers alias la commande ls à une version de ls qui comprend l'indicateur -F. Ce drapeau ajoute un caractère à chaque nom de sortie (ce n'est pas un fichier ordinaire) indiquant le genre de chose. Ainsi, une barre oblique est la forme correspondant au motif '* /', et l'autre barre oblique est l'indicateur de type ajouté.

Pour se débarrasser de ce problème, vous pouvez bien sûr définir un alias différent pour ls. Toutefois, pour ne pas appeler temporairement l'alias, vous pouvez ajouter la barre oblique inverse à la commande suivante:

\ ls -d * /


11
2017-10-28 23:05



Je viens d'ajouter ceci à mon .bashrc fichier (vous pouvez aussi simplement le taper sur la ligne de commande si vous avez seulement besoin d'une session)

alias lsd='ls -ld */'

alors lsd produira le résultat désiré.


9
2018-06-02 23:02



Si le répertoire caché n'est pas nécessaire pour être listé, j'offre:

ls -l | grep "^d" | awk -F" " '{print $9}'  

Et si des répertoires cachés sont nécessaires pour être listés, utilisez:

ls -Al | grep "^d" | awk -F" " '{print $9}'

OU

find -maxdepth 1 -type d | awk -F"./" '{print $2}'

7
2017-08-29 10:21



pour afficher les listes de dossiers sans /

ls -d */|sed 's|[/]||g'

6
2017-10-31 04:07



Voici ce que j'utilise

ls -d1 /Directory/Path/*;


5
2018-01-15 18:10