Antworten:
Haftungsausschluss: Diese Antwort befasst sich speziell mit Bash, aber ein Großteil davon bezieht sich auf die Frage nach Glob-Mustern!
Das Sternchen ( *
) ist ein Platzhalter. Es gibt eine Reihe von Zeichen, die an die Stelle von treten, und das erste Zeichen, das ein Punkt ( .
) ist, gehört nicht dazu. Dies ist nur aufgrund der Funktionsweise der Unix-Dateisysteme ein Sonderfall. Dateien, die mit einem Punkt beginnen, gelten als "versteckt". Das bedeutet , dass Werkzeuge wie cp
, ls
etc. werden nicht „sehen“ , sofern nicht ausdrücklich so zu tun , erzählt.
Lassen Sie uns zunächst einige Beispieldaten erstellen.
$ mkdir .dotdir{1,2} regdir{1,2}
$ touch .dotfile{1,2} regfile{1..3}
Nun haben wir also folgendes:
$ tree -a
.
|-- .dotdir1
|-- .dotdir2
|-- .dotfile1
|-- .dotfile2
|-- regdir1
|-- regdir2
|-- regfile1
|-- regfile2
`-- regfile3
Lass uns jetzt ein paar Spiele spielen. Mit dem Befehl können Sie echo
herausfinden, wie ein bestimmtes Platzhalterzeichen ( *
) für einen bestimmten Befehl aussehen würde:
$ echo *
regdir1 regdir2 regfile1 regfile2 regfile3
$ echo reg*
regdir1 regdir2 regfile1 regfile2 regfile3
$ echo .*
. .. .dotdir1 .dotdir2 .dotfile1 .dotfile2
$ echo .* *
. .. .dotdir1 .dotdir2 .dotfile1 .dotfile2 regdir1 regdir2 regfile1 regfile2 regfile3
$ echo .dotdir*
.dotdir1 .dotdir2
Sie können den Befehl verwenden shopt -s dotglob
, um das Verhalten der zu ändern, *
so dass neben Dateien wie regfile1
es auch übereinstimmt .dotfile1
.
Auszug aus der bash
Manpage
dotglob If set, bash includes filenames beginning with a `.' in the results
of pathname expansion.
Beispiel:
$ shopt -s dotglob
$ echo *
.dotdir1 .dotdir2 .dotfile1 .dotfile2 regdir1 regdir2 regfile1 regfile2 regfile3
Sie können dieses Verhalten mit diesem Befehl rückgängig machen:
$ shopt -u dotglob
$ echo *
regdir1 regdir2 regfile1 regfile2 regfile3
Für Sie sagen Sie, cp
dass Sie alle Dateien kopieren möchten, die dem Muster entsprechen *
, und dass keine Dateien vorhanden sind.
$ cp foo/.* .
Oder Sie können dies tun, wenn Sie alles im foo
Ordner haben möchten :
$ cp foo .
Oder Sie können explizit sein:
$ cp foot/.* foo/* .
Eine kompaktere Form mit Klammererweiterung in bash
:
$ cp foo/{.,}* .
Sie können den echo
Trick jederzeit verwenden, um die von Ihnen vorgeschlagenen Dateimuster zu ermitteln (dies ist der ausgefallene Begriff für das, woraus der Stern besteht).
$ echo {.,}*
. .. .dotdir1 .dotdir2 .dotfile1 .dotfile2 abc regdir1 regdir2 regfile1 regfile2 regfile3
Übrigens, wenn Sie ein Verzeichnis mit Dateien und anderen Verzeichnissen kopieren, möchten Sie dies normalerweise rekursiv tun. Das ist der -R
Wechsel zu cp
:
$ cp -R foo/. .
shopt -s dotglob
, echo *
dann gibt:.dotdir1 .dotdir2 .dotfile1 .dotfile2 regdir1 regdir2 regfile1 regfile2 regfile3
cp -r foo .
wird in der Regel nicht funktionieren, da cp
sich weigern, foo
über sich selbst zu kopieren , meinten Sie wahrscheinlich cp -R foo/. .
. (Beachten Sie, dass dies cp -R
der Standard ist).
zsh
nicht .
und ..
in der Erweiterung von .*
. In zsh
, wenn ein Muster nicht übereinstimmt, wird der Befehl abgebrochen wird (ganz vernünftig wieder), so im allgemeinen Fall, cp foo/{,.}* .
wird scheitern , wenn es keine versteckten ist oder keine nicht-versteckten Dateien.
shopt
nicht existiert.
Mit zsh
wird D
normalerweise das Glob-Qualifikationsmerkmal verwendet (um [D] ot-Dateien einzuschließen):
cp foo/*(D) .
Beachten Sie, dass D
zsh-Globs .
weder mit noch ohne enthalten ..
(wie zu erwarten).
Die Shell behandelt diese Dateien als versteckt, wenn sie das *
Zeichen auflöst. Sie cp
erhält daher keinen dieser Dateinamen als Argumente.
Sie können sie durch explizite Angabe kopieren cp foo/.* .
Wenn Sie alle Dateien und Verzeichnisse von einem Ort an einen anderen kopieren möchten, können Sie den Standardbefehl verwenden rsync
. Im obigen Beispiel geben Sie Folgendes an:
mkdir foo && touch foo/.test
rsync -a foo/ .
kopiert rekursiv den gesamten Inhalt von foo
, einschließlich versteckter Dateien und Verzeichnisse, in das aktuelle Verzeichnis. Der abschließende Schrägstrich am Ende von foo/
ist für rsync wichtig. damit werden nur die inhalte von foo
kopiert, ohne dass es rsync kopiert foo
. Beispielsweise:-
mkdir src && mkdir dest && touch src/.test
rsync -a src dest // copies 'src' contents to 'dest/src'
rsync -a src/ dest // copies 'src' contents to 'dest'
Es gibt viele andere Optionen zur Optimierung von Rsync, einschließlich des Kopierens zwischen Computern.
Die zsh- Antwort von Stéphane Chazelas ist für einen einzelnen Ausdruck mit einem Globus richtig. Wenn Sie es jedoch standardmäßig für alle Ausdrücke festlegen möchten, können Sie verwenden
setopt GLOB_DOTS
Legen Sie es in Ihr ~/.zshrc
, um es dauerhaft zu machen.
dotglob
wirdglobdots
von zsh übersetzt, was ein ungültiger Optionsname für bash ist .