Odpowiedzi:
Uwaga: Ta odpowiedź dotyczy Basha, ale w dużej mierze dotyczy pytania dotyczącego globalnych wzorców!
Znak gwiazdy ( *) to symbol wieloznaczny. Istnieje pewien zestaw znaków, który zajmie miejsce, a pierwszy znak będący kropką ( .) nie jest jednym z nich. Jest to szczególny przypadek tylko ze względu na to, jak działają systemy plików Uniksa, pliki zaczynające się od kropki są uważane za „ukryte”. Oznacza to, że narzędzia takie jak cp, lsitp nie „widzą” je, chyba że wyraźnie powiedziano, aby to zrobić.
Najpierw stwórzmy przykładowe dane.
$ mkdir .dotdir{1,2} regdir{1,2}
$ touch .dotfile{1,2} regfile{1..3}
Więc teraz mamy następujące:
$ tree -a
.
|-- .dotdir1
|-- .dotdir2
|-- .dotfile1
|-- .dotfile2
|-- regdir1
|-- regdir2
|-- regfile1
|-- regfile2
`-- regfile3
Teraz zagrajmy w kilka gier. Możesz użyć polecenia, echoaby wyświetlić listę konkretnych symboli wieloznacznych ( *) dla danego polecenia, takich jak:
$ 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
Możesz użyć tego polecenia, shopt -s dotglobaby zmienić zachowanie *tak, aby oprócz podobnych plików regfile1również pasowały .dotfile1.
fragment strony bashman
dotglob If set, bash includes filenames beginning with a `.' in the results
of pathname expansion.
Przykład:
$ shopt -s dotglob
$ echo *
.dotdir1 .dotdir2 .dotfile1 .dotfile2 regdir1 regdir2 regfile1 regfile2 regfile3
Możesz przywrócić to zachowanie za pomocą tego polecenia:
$ shopt -u dotglob
$ echo *
regdir1 regdir2 regfile1 regfile2 regfile3
Dla ciebie mówisz cp, że chcesz skopiować wszystkie pliki, które pasują do wzorca *, i nie ma żadnych plików.
$ cp foo/.* .
Możesz to zrobić, jeśli chcesz wszystko w foofolderze:
$ cp foo .
Lub możesz wyrazić się jasno:
$ cp foot/.* foo/* .
Bardziej kompaktowa forma wykorzystująca rozszerzenie nawiasów w bash:
$ cp foo/{.,}* .
W dowolnym momencie możesz użyć tej echosztuczki, aby zobaczyć, jakie są proponowane wzorce plików (to fantazyjne określenie tego, co jest częścią gwiazdy).
$ echo {.,}*
. .. .dotdir1 .dotdir2 .dotfile1 .dotfile2 abc regdir1 regdir2 regfile1 regfile2 regfile3
Nawiasem mówiąc, jeśli zamierzasz skopiować katalog plików + inne katalogi, zwykle chcesz to zrobić rekurencyjnie, to jest -Rprzejście do cp:
$ cp -R foo/. .
shopt -s dotglob, echo *a następnie daje:.dotdir1 .dotdir2 .dotfile1 .dotfile2 regdir1 regdir2 regfile1 regfile2 regfile3
cp -r foo .zazwyczaj nie będzie działać, ponieważ cpodmówi kopiowania foonad sobą, prawdopodobnie miałeś na myśli cp -R foo/. .. (zwróć uwagę, że cp -Rjest to standard).
zshnie obejmuje .i nie ..rozwija .*. W zshprzypadku, gdy wzorzec nie pasuje, polecenie zostanie przerwane (całkiem rozsądnie ponownie), więc w ogólnym przypadku cp foo/{,.}* .zakończy się niepowodzeniem, jeśli nie będzie żadnych ukrytych plików lub nie ukrytych plików.
shoptnie istnieje.
Za pomocą zsh, typowym sposobem jest użycie D kwalifikatora glob (aby dołączyć pliki [D] ot):
cp foo/*(D) .
Zauważ, że z lub bez Dglobs zsh nigdy nie zawiera .ani ..(jak można się spodziewać).
Powłoka traktuje te pliki jako ukryte, kiedy rozpoznaje *znak, więc cpnie otrzymuje żadnej z tych nazw plików jako argumentów.
Możesz je skopiować, wyraźnie zaznaczając cp foo/.* .
Jeśli chcesz skopiować wszystkie pliki i katalogi z jednego miejsca do drugiego, możesz użyć standardowego rsyncpolecenia. W podanym powyżej przykładzie:
mkdir foo && touch foo/.test
rsync -a foo/ .
będzie rekurencyjnie kopiować całą zawartość foo, w tym ukryte pliki i ukryte katalogi, do bieżącego katalogu. Końcowy ukośnik na końcu foo/jest ważny dla rsync; z nim fookopiowana jest tylko zawartość pliku, bez niego rsync również skopiuje foo. Na przykład:-
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'
Istnieje wiele innych opcji dostrojenia rsync, w tym kopiowanie między komputerami.
dotglobjest tłumaczoneglobdotsprzez zsh, który jest niepoprawną nazwą opcji dla bash .