Listing uniquement des répertoires utilisant ls dans bash: un examen

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

Que fait exactement le modèle */?

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

722
demandé sur guaka 2013-01-16 10:07:00

22 réponses

*/ est un modèle qui correspond à tous les sous-répertoires du répertoire courant ({[1] } correspondrait à tous les sous-répertoires et; le / Le limite aux répertoires). De même, pour lister tous les sous-répertoires sous/home/alice / Documents, utilisez ls -d /home/alice/Documents/*/

767
répondu Gordon Davisson 2013-01-16 06:11:28

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

1. Utilisation de echo

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

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

2. Utiliser ls uniquement

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

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

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

3. En utilisant ls et grep

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

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 contient espace.)

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

cs  
draft  
files  
hacks  
masters  
static

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

cs/  
draft/  
files/  
hacks/  
masters/  
static/
388
répondu Albert 2018-02-04 14:42:21

J'utilise:

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

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

Mes deux cents.

76
répondu Thomas Altfather Good 2014-02-27 15:40:29

Pour tous les dossiers sans sous-dossiers:

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

Pour tous les dossiers avec sous-dossiers:

find /home/alice/Documents -type d
40
répondu at3m 2014-07-23 08:38:11

4 (Plus) Options fiables.

Un non cotées astérisque * sera interprété comme un motif (glob) par le shell.
le shell l'utilisera dans l'extension pathname.{[33] } Il va ensuite générer une liste de noms de fichiers qui correspondent au modèle.
un astérisque simple correspond à tous les noms de fichiers dans le PWD (répertoire de travail actuel).
Un modèle plus complexe comme {[12] } correspondra à tous les noms de fichiers qui se terminent par /.
Ainsi, tous les répertoires. C'est pourquoi l' commande:

1.- echo.

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

Sera étendu (par le shell) à echo tous les répertoires du PWD.


Pour tester ceci: créez un répertoire (mkdir) nommé comme test-dir, et cd dans celui-ci:

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 déroutante.


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. L'option -d de {[19] } permet de lister l'entrée de répertoire actuelle au lieu du contenu de chaque répertoire (tel que présenté par défaut).

ls -d */

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

2.- ls

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

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

3.- printf

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

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

Et, mieux encore, nous pourrions supprimer la fin /:

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

Une tentative comme celle-ci:

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

Échouera sur:

  • certains noms (ls -d */) comme déjà indiqué ci-dessus.
  • sera affecté par la valeur de IFS.
  • fractionnera les noms sur les espaces et les onglets (avec IFS par défaut).
  • chaque nouvelle ligne du nom démarre une nouvelle commande echo.

4.- Fonction

Enfin, l'utilisation de la liste d'arguments dans une fonction n'affectera pas la liste d'arguments du shell en cours d'exécution. Tout 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
répondu 2016-05-16 18:47:18

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

$ 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 uniquement les répertoires, sans l'arborescence ascii, et avec le chemin complet du 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 alors le chemin absolu, vous pouvez commencer par spécifier le chemin complet vers le courant répertoire:

$ 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 max des 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 peut être vu avec homme arbre

14
répondu Hamish Downer 2015-06-16 15:30:39

Au cas où vous vous demanderiez pourquoi la sortie de 'ls-D * /' vous donne Deux barres obliques de fin , comme:

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

C'est probablement parce que quelque part vos fichiers de configuration de shell ou de session alias la commande ls à une version de ls qui inclut l'indicateur-F. Ce drapeau ajoute un caractère à chaque nom de sortie (ce n'est pas un fichier simple) indiquant le genre de chose qu'il est. Donc, une barre oblique est le from 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. Cependant, pour ne pas appeler Temporairement l'alias, vous pouvez ajouter la commande avec une barre oblique inverse:

\ ls-D * /

11
répondu gwideman 2017-03-31 19:55:44

Je viens d'ajouter ceci à mon fichier .bashrc (vous pouvez également le taper sur la ligne de commande si vous n'en avez besoin que pour une session)

alias lsd='ls -ld */'

Ensuite, le lsd produira le résultat souhaité.

9
répondu guesty guesterson 2016-06-03 00:20:09

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

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

Et si les répertoires cachés doivent être répertoriés, utilisez:

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

Ou

find -maxdepth 1 -type d | awk -F"./" '{print $2}'
7
répondu PHP Learner 2015-08-29 10:21:43

Pour afficher les listes de dossiers sans /

ls -d */|sed 's|[/]||g'
6
répondu wholanda 2014-10-31 08:38:48

Voici ce que j'utilise

ls -d1 /Directory/Path/*;

5
répondu Banning 2015-01-15 18:10:23

Solution réelle ls, y compris les liens symboliques vers les répertoires

Beaucoup de réponses ici n'utilisent pas réellement ls (ou ne l'utilisent que dans le sens trivial de ls -d, tout en utilisant des caractères génériques pour la correspondance du sous-répertoire réel. Une VRAIE solution ls est utile, car elle permet l'utilisation d'options ls pour trier l'ordre, etc.

À L'exclusion des liens symboliques

Une solution utilisant ls a été donnée, mais elle fait quelque chose de différent des autres solutions en ce sens qu'elle exclut liens symboliques {[25] } vers les répertoires:

ls -l | grep '^d'

(éventuellement passer par sed ou awk pour isoler les noms de fichiers)

Y compris les liens symboliques

Dans le cas (probablement plus commun) où les liens symboliques vers les répertoires devraient être inclus, nous pouvons utiliser l'option -p de ls:

ls -1p | grep '/$'

Ou, se débarrasser des barres obliques de fin:

ls -1p | grep '/$' | sed 's/\/$//'

, Nous pouvons ajouter des options à ls si besoin (si une longue liste est utilisée, la -1 n'est plus requis).

Note: si nous voulons barres obliques de fin, mais ne voulons pas les mettre en surbrillance par grep, nous pouvons supprimer hackishly la surbrillance en rendant la partie correspondante réelle de la ligne vide:

ls -1p | grep -P '(?=/$)'
5
répondu pyrocrasty 2018-03-10 21:31:27

Tester si l'élément est un répertoire avec test -d:

for i in $(ls); do test -d $i && echo $i ; done
4
répondu nmarques 2017-10-30 02:56:45

One-liner pour lister les répertoires uniquement à partir de "ici".

Avec le nombre de fichiers.

for i in `ls -d */`; do g=`find ./$i -type f -print| wc -l`; echo "Directory $i contains $g files."; done
2
répondu BHG 2014-07-16 21:13:22

*/ est un modèle de correspondance de nom de fichier qui correspond aux répertoires du répertoire courant.

Pour lister uniquement les répertoires, j'aime cette fonction:

# long list only directories
llod () { 
  ls -l --color=always "$@" | grep --color=never '^d'
}

Mettez-le dans votre .bashrc.

Exemples d'Utilisation:

llod       # long listing of all directories in current directory
llod -tr   # same but in chronological order oldest first
llod -d a* # limit to directories beginning with letter 'a'
llod -d .* # limit to hidden directories

Remarque: Il se cassera si vous utilisez l'option -i. Voici un correctif pour cela:

# long list only directories
llod () { 
  ls -l --color=always "$@" | egrep --color=never '^d|^[[:digit:]]+ d'
}
2
répondu Robin A. Meade 2015-03-25 20:16:01

Pour info, si vous voulez imprimer tous les fichiers en multi-ligne, vous pouvez faire un ls -1 qui permet d'imprimer chaque fichier dans une ligne distincte. fichier1 fichier2 fichier3

2
répondu warfreak92 2016-02-15 14:40:09

En Utilisant Perl:

ls | perl -nle 'print if -d;'
2
répondu Paul-Gerhard Woolcock 2017-10-20 22:08:22

Pour lister uniquement les répertoires :

ls -l | grep ^d

Pour lister uniquement les fichiers :

ls -l | grep -v ^d 

Ou aussi vous pouvez faire comme: ls-ld * /

2
répondu Vijay Gawas 2018-08-13 12:52:58

J'ai partiellement résolu avec :

cd "/path/to/pricipal/folder"

for i in $(ls -d .*/); do sudo ln -s "$PWD"/${i%%/} /home/inukaze/${i%%/}; done

ln: «/home/inukaze/./.»: can't overwrite a directory
ln: «/home/inukaze/../..»: can't overwrite a directory
ln: accesing to «/home/inukaze/.config»: too much symbolics links levels
ln: accesing to «/home/inukaze/.disruptive»: too much symbolics links levels
ln: accesing to «/home/inukaze/innovations»: too much symbolics links levels
ln: accesing to «/home/inukaze/sarl»: too much symbolics links levels
ln: accesing to «/home/inukaze/.e_old»: too much symbolics links levels
ln: accesing to «/home/inukaze/.gnome2_private»: too much symbolics links levels
ln: accesing to «/home/inukaze/.gvfs»: too much symbolics links levels
ln: accesing to «/home/inukaze/.kde»: too much symbolics links levels
ln: accesing to «/home/inukaze/.local»: too much symbolics links levels
ln: accesing to «/home/inukaze/.xVideoServiceThief»: too much symbolics links levels

Eh bien, cela me réduit, la partie maire:)

1
répondu inukaze 2014-11-28 10:45:46

En ajoutant pour le faire cercle complet, pour récupérer le chemin de chaque dossier, utilisez une combinaison de la réponse D'Albert ainsi que des Gordans qui devraient être assez utiles.

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

Sortie:

/pathto/parent/folder/childfolder1/
/pathto/parent/folder/childfolder2/
/pathto/parent/folder/childfolder3/
/pathto/parent/folder/childfolder4/
/pathto/parent/folder/childfolder5/
/pathto/parent/folder/childfolder6/
/pathto/parent/folder/childfolder7/
/pathto/parent/folder/childfolder8/
1
répondu BilliAm 2014-12-30 05:45:28

Essayez celui-ci. cela fonctionnera sur toutes les distributions ls-ltr / grep drw

1
répondu Raj RD 2018-06-22 21:49:19
file *|grep directory

O / P (sur ma machine) --

[root@rhel6 ~]# file *|grep directory
mongo-example-master:    directory
nostarch:                directory
scriptzz:                directory
splunk:                  directory
testdir:                 directory

Ci-dessus sortie peut être raffiné plus en utilisant cut .

file *|grep directory|cut -d':' -f1
mongo-example-master
nostarch
scriptzz
splunk
testdir

* could be replaced with any path that's permitted
 file - determine file type
 grep - searches for string named directory
 -d - to specify a field delimiter
 -f1 - denotes field 1
0
répondu AVS 2017-10-05 18:56:52