it-swarm.com.de

Nur Verzeichnisse auflisten, die ls in bash verwenden: Eine Prüfung

Dieser Befehl listet Verzeichnisse im aktuellen Pfad auf: ls -d */

Was genau macht das Muster */?

Und wie können wir den absoluten Pfad im obigen Befehl (z. B. ls -d /home/alice/Documents) angeben, um nur Verzeichnisse in diesem Pfad aufzulisten?

791
Sibi

*/ ist ein Muster, das mit allen Unterverzeichnissen im aktuellen Verzeichnis übereinstimmt (* würde mit allen Unterverzeichnissen und übereinstimmen; das / beschränkt sich auf Verzeichnisse). Verwenden Sie ls -d /home/alice/Documents/*/, um alle Unterverzeichnisse unter/home/alice/Documents aufzulisten.

843
Gordon Davisson

Vier Möglichkeiten, dies zu erreichen, jeweils mit einem anderen Ausgabeformat

1. Verwendung von echo

Beispiel: echo */, echo */*/
Hier ist was ich habe: 

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

2. Nur mit ls

Beispiel: ls -d */
Hier ist genau das, was ich bekam: 

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

Oder als Liste (mit Detailinformationen): ls -dl */ 

3. Verwendung von ls und grep

Beispiel: ls -l | grep "^d"Hier ist was ich habe:

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. Bash-Skript (Nicht empfohlen für Dateinamen mit Leerzeichen)

Beispiel: for i in $(ls -d */); do echo ${i%%/}; done
Hier ist was ich habe:

cs  
draft  
files  
hacks  
masters  
static

Wenn Sie '/' als Endzeichen haben möchten, lautet der Befehl: for i in $(ls -d */); do echo ${i}; done

cs/  
draft/  
files/  
hacks/  
masters/  
static/
423
Albert

Ich benutze:

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

Dadurch wird eine einzelne Spalte ohne nachstehenden Schrägstrich erstellt - nützlich für Skripts.

Meine zwei Cent.

80

Für alle Ordner ohne Unterordner:

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

Für alle Ordner mit Unterordner:

find /home/alice/Documents -type d
46
at3m

4 (mehr) zuverlässige Optionen.

Ein nicht in Anführungszeichen Sternchen * wird von der Shell als Muster (Glob) interpretiert.
Die Shell verwendet es für die Erweiterung des Pfadnamens.
Daraufhin wird eine Liste von Dateinamen generiert, die dem Muster entsprechen.
Ein einfaches Sternchen entspricht allen Dateinamen in der PWD (aktuelles Arbeitsverzeichnis).
Ein komplexeres Muster als */ stimmt mit allen Dateinamen überein, die mit / enden.
Also alle Verzeichnisse. Deshalb der Befehl:

1. Echo.

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

wird (von der Shell) auf echo alle Verzeichnisse in der PWD erweitert.


Um dies zu testen: Erstellen Sie ein Verzeichnis (mkdir) mit dem Namen test-dir und cd:

mkdir test-dir; cd test-dir

Erstellen Sie einige Verzeichnisse:

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:

Der Befehl echo ./*/ bleibt auch bei ungeraden benannten Dateien zuverlässig:

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

Aber die Leerzeichen in Dateinamen machen das Lesen etwas verwirrend.


Wenn wir anstelle von echols verwenden, erweitert die Shell immer noch die Liste der Dateinamen. Die Shell ist der Grund, eine Liste der Verzeichnisse in der PWD abzurufen. Mit der -d-Option für ls wird der aktuelle Verzeichniseintrag anstelle des Inhalts jedes Verzeichnisses (wie standardmäßig angezeigt) angezeigt.

ls -d */

Dieser Befehl ist jedoch (etwas) weniger zuverlässig. Es wird mit den oben aufgeführten ungeraden benannten Dateien fehlschlagen. Es wird mit mehreren Namen ersticken. Sie müssen einen nach dem anderen löschen, bis Sie diejenigen mit Problemen finden.

2.- ls

Das GNU ls akzeptiert die Taste "Ende der Optionen" (--).

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

3.-printf

Um jedes Verzeichnis in einer eigenen Zeile aufzulisten (in einer Spalte, ähnlich wie bei ls -1), verwenden Sie:

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

Und noch besser, wir könnten den nachfolgenden / entfernen:

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

Ein Versuch wie dieser:

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

Wird fehlschlagen am:

  • einige Namen (ls -d */) wie bereits oben gezeigt.
  • wird durch den Wert von IFS beeinflusst.
  • teilt Namen auf Leerzeichen und Registerkarten auf (mit dem Standardwert IFS).
  • jede neue Zeile im Namen startet einen neuen Echo-Befehl.

4.- Funktion

Die Verwendung der Argumentliste innerhalb einer Funktion wirkt sich nicht auf die Liste der Argumente der aktuellen Shell aus. Einfach:

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

präsentiert diese Liste:

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

Diese Optionen sind bei verschiedenen Typen ungerader Dateinamen sicher.

32
user2350426

Der Befehl tree ist auch hier sehr nützlich. Standardmäßig werden alle Dateien und Verzeichnisse vollständig dargestellt, wobei einige ASCII-Zeichen den Verzeichnisbaum anzeigen.

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

Wenn wir jedoch nur die Verzeichnisse ohne den ASCII-Baum und mit dem vollständigen Pfad aus dem aktuellen Verzeichnis erhalten möchten, können Sie Folgendes tun:

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

Die Argumente lauten:

-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.

Wenn Sie dann den absoluten Pfad wünschen, können Sie zunächst den vollständigen Pfad zum aktuellen Verzeichnis angeben:

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

Und um die Anzahl der Unterverzeichnisse einzuschränken, können Sie die maximale Ebene der Unterverzeichnisse mit -L level einstellen, z.

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

Weitere Argumente können mit man tree gesehen werden

16
Hamish Downer

Falls Sie sich fragen, warum die Ausgabe von 'ls -d * /' Ihnen zwei nachstehende Schrägstriche gibt, wie:

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

es liegt wahrscheinlich daran, dass irgendwo Ihre Shell- oder Session-Konfigurationsdateien den Befehl ls auf eine Version von ls setzen, die das -F-Flag enthält. Dieses Flag hängt an jeden Ausgabenamen (das ist keine einfache Datei) ein Zeichen, das die Art der Sache angibt. Ein Schrägstrich entspricht also dem Muster '* /' und der andere Schrägstrich ist der angehängte Typindikator.

Um dieses Problem zu beseitigen, können Sie natürlich einen anderen Alias ​​für ls definieren. Um den Alias ​​jedoch vorübergehend nicht aufzurufen, können Sie den Befehl mit einem umgekehrten Schrägstrich voranstellen:

\ ls -d * /

11
gwideman

Ich füge dies einfach zu meiner .bashrc-Datei hinzu (Sie könnten es auch einfach in die Befehlszeile eingeben, wenn Sie es nur für eine Sitzung benötigen).

alias lsd='ls -ld */'

dann erzeugt lsd das gewünschte ergebnis.

9

Wenn verstecktes Verzeichnis nicht benötigt wird, biete ich an:

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

Wenn versteckte Verzeichnisse aufgelistet werden müssen, verwenden Sie:

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

OR

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

um Ordnerlisten ohne / anzuzeigen

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

Nur zum Auflisten von Verzeichnissen :

ls -l | grep ^d

nur zum Auflisten von Dateien :

ls -l | grep -v ^d 

oder auch als: ls -ld * /

6
Vijay Gawas

Aktuelle ls-Lösung, einschließlich symbolischer Links zu Verzeichnissen

Viele Antworten hier verwenden ls nicht (oder verwenden sie nur im trivialen Sinn von ls -d, wenn Sie Platzhalter für die tatsächliche Übereinstimmung des Unterverzeichnisses verwenden. Eine echte ls-Lösung ist hilfreich, da sie die Verwendung von ls-Optionen für die Sortierreihenfolge usw. ermöglicht .

Symlinks ausschließen

Es wurde eine Lösung mit ls angegeben, die sich jedoch von den anderen Lösungen unterscheidet, indem sie ausgenommen Symlinks auf Verzeichnisse:

ls -l | grep '^d'

(möglicherweise durch sed oder awk geleitet, um die Dateinamen zu isolieren)

Einschließlich Symlinks

In dem (wahrscheinlich häufigeren) Fall, in dem Symlinks zu Verzeichnissen enthalten sein sollen, können wir die -p-Option von ls verwenden:

ls -1p | grep '/$'

oder die nachfolgenden Schrägstriche loswerden:

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

Wir können ls nach Bedarf Optionen hinzufügen (wenn ein langer Eintrag verwendet wird, ist der -1 nicht mehr erforderlich).

note: Wenn wir wollen nachgestellte Schrägstriche sind, sie jedoch nicht durch grep hervorgehoben werden sollen, können wir die Hervorhebung hackhaft entfernen, indem der tatsächlich übereinstimmende Teil der Zeile leer bleibt:

ls -1p | grep -P '(?=/$)'
5
pyrocrasty

Hier ist was ich benutze 

ls -d1 /Directory/Path/*;

5
Banning

Testen Sie, ob das Element ein Verzeichnis mit test -d ist:

for i in $(ls); do test -d $i && echo $i ; done
4
nmarques

*/ ist ein Dateinamensvergleichsmuster, das den Verzeichnissen im aktuellen Verzeichnis entspricht.

Um nur Verzeichnisse aufzulisten, gefällt mir diese Funktion:

# long list only directories
llod () { 
  ls -l --color=always "[email protected]" | grep --color=never '^d'
}

Legen Sie es in Ihre .bashrc.

Anwendungsbeispiele:

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

HINWEIS: Wenn Sie die -i-Option verwenden, wird es beschädigt. Hier ist ein Fix dafür:

# long list only directories
llod () { 
  ls -l --color=always "[email protected]" | egrep --color=never '^d|^[[:digit:]]+ d'
}
2
Robin A. Meade

Zu Ihrer Information, wenn Sie alle Dateien in mehreren Zeilen drucken möchten, können Sie einen ls -1 ausführen, der jede Datei in einer separaten Zeile druckt. Datei1 Datei2 Datei3

2
warfreak92

Einzeiler, um Verzeichnisse nur von "hier" aufzulisten.

Mit Dateizählung.

for i in `ls -d */`; do g=`find ./$i -type f -print| wc -l`; echo "Directory $i contains $g files."; done
2
BHG

Perl verwenden:

ls | Perl -nle 'print if -d;'

Probier diese. Dies funktioniert auf allen Distrosls -ltr | grep drw

1
Raj RD

Ich habe teilweise gelöst mit:

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

Nun, das reduziert für mich den Bürgermeisteranteil :)

1
inukaze

Um die ursprüngliche Frage zu beantworten, hat */ nichts mit ls an sich zu tun; Es wird von der Shell/Bash in einem Prozess ausgeführt, der als globbing bekannt ist.

Deshalb geben echo */ und ls -d */ die gleichen Elemente aus. (Das Flag -d bewirkt, dass ls die Verzeichnisnamen und nicht den Inhalt der Verzeichnisse ausgibt.)

1
flow2k

Um den Pfad eines jeden Ordners abzurufen, verwenden Sie eine Kombination aus Alberts Antwort und Gordans, die ziemlich nützlich sein sollten.

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

Ausgabe:

/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
BilliAm

Eine einfache Auflistung des aktuellen Verzeichnisses wäre:

ls -1d ./*/

Möchten Sie es sortieren und reinigen?

ls -1d ./*/ | cut -c 3- | rev | cut -c 2- | rev | sort
0
PYK

Ich verwende hier nur die Verzeichnisnamen:

ls -1d /some/folder/*/ | awk -F "/" "{print \$(NF-1)}"
0
Robert Lujo
file *|grep directory

O/P (auf meiner Maschine) - 

[[email protected] ~]# file *|grep directory
mongo-example-master:    directory
nostarch:                directory
scriptzz:                directory
splunk:                  directory
testdir:                 directory

Die obige Ausgabe kann durch den Einsatz von Schnitt verfeinert werden.

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
AVS

Hier ist eine Variation mit Tree, die Verzeichnisnamen nur in separaten Zeilen ausgibt. Ja, es ist hässlich, aber hey, es funktioniert.

tree -d | grep -E '^[├|└]' | cut -d ' ' -f2

oder mit awk

tree -d | grep -E '^[├|└]' | awk '{print $2}'

Dies ist jedoch wahrscheinlich besser und behält den / nach dem Verzeichnisnamen bei.

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