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?
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/*/
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/
J'utilise:
ls -d */ | cut -f1 -d'/'
Cela crée une seule colonne sans barre oblique finale-utile dans les scripts.
Mes deux cents.
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
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.
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
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 * /
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é.
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}'
Pour afficher les listes de dossiers sans /
ls -d */|sed 's|[/]||g'
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 '(?=/$)'
Tester si l'élément est un répertoire avec test -d
:
for i in $(ls); do test -d $i && echo $i ; done
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
*/
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'
}
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
En Utilisant Perl:
ls | perl -nle 'print if -d;'
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 * /
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:)
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/
Essayez celui-ci. cela fonctionnera sur toutes les distributions ls-ltr / grep drw
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