*
to glob rozwinięty przez powłokę. Domyślnie powłoki nie zawierają plików, których nazwa zaczyna się od .
(zwanych plikami ukrytymi lub plikami dotfiles), chyba że wiodące hasło .
jest wprowadzone dosłownie.
*
lub [.]*
lub ?*
lub *.*
lub dir/*
nie będzie zawierać plików kropkowych.
.*
lub dir/.*
będzie.
Więc możesz zrobić:
mv -- * .* /dest/
jednak niektóre powłoki, w tym bash
(ale nie zsh
, mksh
ani nie fish
), mają tę wadę, że rozszerzenie .*
zawiera .
i ..
specjalne pozycje katalogu, których tu nie chcesz (i generalnie nigdy nie chcesz, aby glob zawierał, dlatego nazywam to błędem).
Z tego powodu okaże się, że czasami ludzie używają (w powłokach podobnych do Bourne'a):
mv -- * .[!.]* ..?* /dest/
To trzy globusy, pierwszy pasujący do nie ukrytych plików, drugi z nazwami plików rozpoczynającymi się od, .
po którym następuje znak inny niż, .
a trzeci z nazwami plików rozpoczynającymi się od, ..
po którym następuje co najmniej jeden znak.
Jednak niektóre nowoczesne muszle mają na to lepsze sposoby
zsh
Za zsh
pomocą (D)
kwalifikatora glob można określić, że glob powinien zawierać pliki kropkowe:
mv -- *(D) /dest/
zsh
naprawiono również tę inną wadę powłoki Bourne'a, ponieważ jeśli wzorzec nie pasuje, mv
polecenie nie jest uruchamiane.
Jak powiedziano powyżej, nigdy też nie będzie zawierać .
ani ..
w swoich globach, więc
mv -- * .* /dest/
będzie bezpieczny. Jeśli jednak nie ma pasującego pliku *
lub żaden plik nie pasuje, .*
polecenie zostanie przerwane, więc lepiej użyć:
mv -- (*|.*) /dest/
Podobnie jak w niektórych innych powłokach, możesz również zmusić wszystkie globusy do dołączania plików dot (na przykład, jeśli chcesz, aby pliki dot były dołączane częściej niż nie):
setopt dotglob
lub:
set -o dotglob
Następnie, jeśli chcesz, aby określony glob nie zawierał plików dot, możesz go napisać:
echo *(^D)
Lub:
echo [^.]*
Grzmotnąć
Niestety bash
nie ma globalnych kwalifikatorów. Pozostaje Ci zatem włączenie globalnego dodawania plików. W bash
składni jest:
shopt -s dotglob
(i używać [^.]*
do globów bez ukrytych plików).
Z dotglob
, bash
nie obejmuje .
ani ..
w globs takich jak *
, ale nadal robi to dla takich globów .*
.
Jeśli ustawisz GLOBIGNORE
zmienną na coś niepustego, wówczas automatycznie włącza dotglob
opcję i wyklucza .
i ..
z .*
globusów, ale nie z globusów dir/.*
lub .*/file
jedynek (!), Dzięki czemu zabezpieczenie jest całkiem bezużyteczne. Mógłbyś zrobić, GLOBIGNORE='*/.:*/..:./*:../*:*/./*:*/../*'
ale wtedy zniszczyłoby globusy takie jak */.
lub ./*
lub ../*
.
Lepszym obejściem jest użycie [.]*
lub dir/[.]*
lub [.]*/file
(z dotglob
włączonym) do rozwijania plików dot, z wyjątkiem .
i ..
.
ryba
fish
globusy nie obejmują .
ani ..
. Gdy nie ma dopasowania, w zależności od wersji, będzie działać jak zsh
(lub bash -o failglob
) lub bash -o nullglob
.
mv -- * .* /dest/
Działa, jeśli istnieją zarówno pliki ukryte, jak i nie ukryte. W przeciwnym razie YMMV i w niektórych wersjach może wywoływać, mv -- /dest
jeśli w ogóle nie ma pliku.
ksh93
W ksh93
żadnym z nich nie ma kwalifikatora glob . Możesz dołączać pliki kropkowe do globów za pomocą:
FIGNORE='@(.|..)'
W przeciwieństwie do bash
tych GLOBIGNORE
, jest to zrobione poprawnie, a także rozwiązuje problem .*
włączenia .
i ..
.
yash
yash
posiada dot-glob
opcję ( set -o dot-glob
), ale wbrew temu bash
, ekspansje glob (nawet z *
) to .
i ..
tak jest całkiem bezużyteczny.
tcsh
set globdot
Działa jak w bash
, to jest *
to kropka pliki wyjątkiem .
a ..
jednak .*
wciąż zawiera .
i ..
(i można użyć [.]*
, aby rozwinąć ukryte pliki z wyjątkiem .
i ..
).