Wie kann ich erreichen, dass Bash `.` und `..` nicht mit `.*` abgleicht?

Wie kann ich erreichen, dass Bash `.` und `..` nicht mit `.*` abgleicht?

Wenn ich versuche, alle Punktdateien in einem Verzeichnis mit abzugleichen, .*scheint dies einen unangenehmen Nebeneffekt zu haben: Neben der Übereinstimmung mit allen (echten) Dateien und Verzeichnissen werden auch .und abgeglichen ...

bash-3.2$ mv test/.* dest/
mv: rename test/. to dest/.: Invalid argument
mv: test/.. and dest/.. are identical

Das scheint wirklich seltsam, da es sich im Grunde genommen um „falsche“ Verzeichnisse handelt, die nur dazu da sind, relative Pfade zu vereinfachen. Sie sind nicht Teil des Inhalts eines Verzeichnisses, und ich möchte nicht, dass sie übereinstimmen, wenn ich versuche, den Inhalt eines Verzeichnisses in ein anderes zu verschieben. Ich kann mir kein Szenario vorstellen, in dem ich eine Übereinstimmung mit wünschen würde .*.

Wie kann ich dies also deaktivieren? (Außer durch die Verwendung der Z-Shell, die nicht immer verfügbar ist und möglicherweise nicht die Shell ist, die von jemandem verwendet wird, der eine von mir geschriebene Funktion ausführt.)

Antwort1

Sie können die Bash-Variable verwenden GLOBIGNORE.

       GLOBIGNORE
              Eine durch Doppelpunkte getrennte Liste von Mustern, die den Satz von Dateinamen definieren
              von der Pfadnamenerweiterung ignoriert werden. Wenn ein Dateiname mit einem
              Das Pfadnamenerweiterungsmuster entspricht auch einem der Muster in
              GLOBIGNORE, es wird aus der Liste der Übereinstimmungen entfernt.

Und

       ......................-. Die Dateinamen ``.'' und ``..'' sind immer
       wird ignoriert, wenn GLOBIGNORE gesetzt und nicht null ist.  

Wenn Sie also

GLOBIGNORE='*/.:*/..'

dann path/.*wird nicht mit .und übereinstimmen .., wie Sie verlangen.

Antwort2

Ein Glob-Muster wäre .[^.]*: Es passt zu etwas mit mindestens 2 Zeichen, wobei das 2. Zeichen kein Punkt ist.

Dokumentation zum Dateinamen-Mustervergleich finden Sie auf der Manpage der Bash oder hier:http://www.gnu.org/software/bash/manual/bash.html#Pattern-Matching


Jonathan Callen bringt einen guten Punkt vor. Sie können ein ziemlich einfaches erweitertes Muster verwenden

shopt -s extglob
ls -d .!(.|)

verwandte Informationen