2016-04-11 8 views
2

Derzeit lernen einige Bash-Skripte und ein Problem mit einer Frage mit der Auflistung aller Dateien in einem bestimmten Verzeichnis und Angabe, ob sie eine Datei oder ein Verzeichnis sind. Das Problem, das ich habe, ist, dass ich nur entweder mein aktuelles Verzeichnis bekomme oder wenn ein Verzeichnis angegeben wird, es wird einfach gesagt, dass es ein Verzeichnis ist, z./home/user/shell_scripts gibt zurück shell_scipts ist ein Verzeichnis und nicht die darin enthaltenen Dateien. Das ist, was ich habe, so weit:Shell-Skript zum Auflisten von Dateien in einem bestimmten Verzeichnis und wenn es Dateien oder Verzeichnisse sind

dir=$dir 
for file in $dir; do 
    if [[ -d $file ]]; then 
     echo "$file is a directory" 
    if [[ -f $file ]]; then 
     echo "$file is a regular file" 
    fi 
done 

Antwort

2

Ihre Linie ersetzen:

for file in $dir; do 

erweitert $dir nur zu einer einzelnen Verzeichniszeichenfolge. Was Sie tun müssen, erweitern Sie das zu einer Liste von Dateien in dem Verzeichnis. Man könnte dies mit dem folgenden tun:

for file in "${dir}/"* ; do 

Dies wird den "${dir}/"* Abschnitt in einen Namen geschützte Liste des aktuellen Verzeichnisses erweitern. Wie Biffen darauf hinweist, sollte dies garantieren, dass die Dateiliste nicht mit geteilten partiellen Dateinamen in file enden wird, wenn einige von ihnen Whitespace enthalten.

Wenn Sie in die Verzeichnisse in dir recurse möchten, dann könnte die Verwendung von find ein besserer Ansatz sein. Verwenden Sie einfach:

for file in $(find ${dir}); do 

Beachten Sie, dass bei einfacher, dies wird nicht Griff Dateien oder Verzeichnisse mit Leerzeichen in ihnen. Aus diesem Grund wäre ich versucht, die Schleife fallen zu lassen und die Ausgabe auf einmal zu generieren. Dies kann etwas anders sein als das, was Sie wollen, aber es ist wahrscheinlich einfacher zu lesen und viel effizienter, vor allem bei einer großen Anzahl von Dateien. Zum Beispiel, um eine Liste aller Verzeichnisse:

find ${dir} -maxdepth 1 -type d 

und die Dateien aufzulisten:

find ${dir} -maxdepth 1 -type f 

, wenn Sie in Verzeichnisse wiederholen wollen unten, dann entfernen Sie die -maxdepth 1

+0

Dies könnte brechen, wenn es wirklich viele Dateien gibt (Befehlszeile zu lang). – user1934428

+0

Ja, es ist _possible_, obwohl ich diesen Ansatz oft für sehr viele Dateien (> 10^5) verwendet habe und kein Problem hatte. Ich wäre versucht, den 'for' /' do'/'done' Ansatz zu verwerfen und, wenn möglich, direkt den' ls' oder 'find' Befehl zu verwenden, was sehr viel effizienter wäre - obwohl ich versuche, in den Anwendungsbereich von die OP-Frage. Ich werde entsprechend aktualisieren. –

+0

Dies funktioniert nicht gut mit Dateinamen, die Leerzeichen oder andere Sonderzeichen enthalten. – Biffen

0
for file in $(ls $dir) 
do 
    [ -f $file ] && echo "$file is File" 
    [ -d $file ] && echo "$file is Directory" 
done 

oder die

$(ls $dir) 

mit

`ls $` 
+0

Dies funktioniert nicht gut mit Dateinamen, die Leerzeichen oder andere Sonderzeichen enthalten. Und was soll "ls $" machen ?! – Biffen

1
ls -F ~ | \ 
sed 's#.*/$#/& is a Directory#;t quit;s#.*#/& is a File#;:quit;s/[*/=>@|]//' 

Die -F Der Schalter "classify" hängt ein "/" an, wenn eine Datei ein Verzeichnis ist. Der sed-Code druckt die gewünschte Nachricht und entfernt dann das Suffix.

+1

Dies funktioniert nicht mit Dateien, deren Name neue Zeilen enthält. – Biffen

+1

Danke @Biffen, das ist erschreckend, Dateinamen mit Zeilenumbrüchen sind ein _thing_? Ich habe sie gerade nachgeschlagen. Einfach gemacht. Habe gerade den obigen ** sed ** Code getestet - was fehlgeschlagen ist. OK, aber wer _newlines dort _wollte, was ist die Geschichte dieses Dinges? Ich bekomme das "Wie" und suche das "Warum" ... – agc

+1

Ich kann das Warum nicht wirklich beantworten, außer mit einem "Warum nicht?". ;) – Biffen

2

Dies ist eine gute Verwendung für globbing:

for file in "$dir/"* 
do 
    [[ -d "$file" ]] && echo "$file is a directory" 
    [[ -f "$file" ]] && echo "$file is a regular file" 
done 

Dies funktioniert sogar, wenn Dateien in $dir haben Sonderzeichen in ihrem Namen, wie zB Leerzeichen, Sternchen und sogar Zeilenumbrüche.

Beachten Sie auch, dass Variablen in Anführungszeichen gesetzt werden sollten ("$file").Aber *muss nicht zitiert werden. Und ich entfernte dir=$dir, da es nichts tut (außer Pause, wenn $dir Sonderzeichen enthält).

Verwandte Themen