2010-01-25 21 views
16

einfach einen einfachen Shell-Skript Witting und wenig verwirrt:Bash for-Schleife mit Wildcards und versteckten Dateien

Hier ist mein Skript:

% for f in $FILES; do echo "Processing $f file.."; done 

Der Befehl:

ls -la | grep bash 

produziert:

% ls -a | grep bash 
.bash_from_cshrc 
.bash_history 
.bash_profile 
.bashrc 

Wenn

FILES=".bash*" 

Ich bekomme die gleichen Ergebnisse (unterschiedliche Formatierung) wie ls -a. Allerdings, wenn

FILES="*bash*" 

ich diese Ausgabe:

Processing *bash* file.. 

Dies ist nicht die erwartete Leistung und nicht das, was ich erwarte. Darf ich am Anfang des Dateinamens keine Wildcard haben? Ist der . am Anfang des Dateinamens "special" irgendwie?

Einstellung

FILES="bash*" 

auch nicht funktioniert.

+1

Wie Nos sagte unten, werden Sie wahrscheinlich ein Bash-Flag verwenden möchten, um das Verhalten zu ändern. (shopt -s dotglob) –

Antwort

6

FILES=".bash*" funktioniert, weil die versteckten Dateien mit einem .

FILES="bash*" funktioniert nicht, weil die versteckten Dateien beginnen Namen beginnen Namen mit einem . kein b

FILES="*bash*" nicht, weil die * Wildcard funktioniert bei Der Beginn einer Zeichenfolge enthält keine versteckten Dateien.

+6

Also wenn ich es machen will, sollte ich FILES = ". * bash *" machen? Aber was, wenn ich versteckte und nicht versteckte Dateien möchte? – sixtyfootersdude

10

Ja, die . an der Front ist etwas Besonderes, und wird in der Regel nicht von einem * Wildcard abgestimmt werden, wie in der bash man-Seite dokumentiert (und in den meisten Unix-Shells):

Wenn ein pattern wird für die Pfadnamenerweiterung verwendet, das Zeichen “. ” am Anfang eines Namens oder unmittelbar nach einem Schrägstrich muss explizit abgeglichen werden, es sei denn, die Shell-Option dotglob ist festgelegt. Wenn ein Pfadname gefunden wird, muss der Schrägstrich immer explizit übereinstimmen. In anderen Fällen ist die “. ” Zeichen wird nicht speziell behandelt.

41

Das Standard-Globbing in bash enthält keine Dateinamen, die mit a beginnen. (auch versteckte Dateien).

können Sie, dass

shopt es dotglob

$ ls -a 
. .. .a .b .c d e f 
$ ls * 
d e f 
$ shopt -s dotglob 
$ ls * 
.a .b .c d e f 
$ 

es mit ändern wieder zu deaktivieren, führen shopt -u dotglob.

+0

Ich vergesse immer über shopt! Danke für diese Antwort! –

8

Wenn Sie versteckte und nicht wollen versteckt, setzen dotglob (bash)

#!/bin/bash 
shopt -s dotglob 
for file in * 
do 
echo "$file" 
done