*
é um glob que é expandido pelo shell. Por padrão, os shells não incluem arquivos cujo nome comece com .
(chamados de arquivos ocultos ou dotfiles), a menos que o .
inicial seja digitado literalmente.
*
ou [.]*
ou ?*
ou *.*
ou dir/*
não incluirão dotfiles.
.*
ou dir/.*
será.
Então você poderia fazer:
mv -- * .* /dest/
no entanto, alguns shells incluindo bash
(mas não zsh
, mksh
nor fish
) têm essa má característica de que a expansão de .*
inclui as entradas de diretório especiais .
e ..
não quero aqui (e geralmente nunca quero um glob para incluir, e é por isso que eu chamo isso de um erro).
Por esse motivo, você descobrirá que às vezes as pessoas usam (em shells semelhantes a Bourne):
mv -- * .[!.]* ..?* /dest/
São três globs, o primeiro que corresponde a arquivos não ocultos, o segundo nome de arquivo começando com .
seguido por um caractere diferente de .
e o terceiro nome de arquivo começando com ..
seguido por pelo menos um caractere .
No entanto, algumas shells modernas têm melhores maneiras de contornar isso
zsh
Com zsh
, você pode usar o qualificador (D)
glob para especificar que o glob deve incluir dotfiles:
mv -- *(D) /dest/
zsh
também corrigiu essa outra má especificação do shell Bourne, pois se o padrão não corresponder, o comando mv
não será executado.
Como dito acima, ele nunca incluirá .
nem ..
em seus globs, então
mv -- * .* /dest/
estará seguro. No entanto, se não houver nenhum arquivo correspondente a *
ou nenhum arquivo correspondente a .*
, o comando será cancelado, portanto, seria melhor usar:
mv -- (*|.*) /dest/
Como em alguns outros shells, você também pode forçar todos os globs a incluírem dotfiles (por exemplo, se você está querendo que os dotfiles sejam incluídos mais frequentemente do que não) com:
setopt dotglob
ou:
set -o dotglob
Depois disso, se você quiser que um glob glob não inclua dotfiles, você pode escrevê-lo:
echo *(^D)
Ou:
echo [^.]*
Bash
Infelizmente bash
não tem qualificadores glob. Então você tem a possibilidade de incluir globalmente a inclusão de arquivos de ponto. Em bash
, a sintaxe é:
shopt -s dotglob
(e use [^.]*
para globs sem arquivos ocultos).
Com dotglob
, bash
não inclui .
nem ..
em globs como *
, mas ainda faz para globs como .*
.
Se você definir a variável GLOBIGNORE
como algo não vazio, ela ativará automaticamente a opção dotglob
e excluirá .
e ..
de .*
globs, mas não de dir/.*
ou .*/file
(!) para que a salvaguarda seja bastante inútil. Você poderia fazer GLOBIGNORE='*/.:*/..:./*:../*:*/./*:*/../*'
, mas isso iria quebrar globs como */.
ou ./*
ou ../*
.
Uma solução melhor é usar [.]*
ou dir/[.]*
ou [.]*/file
(com dotglob
ativado) para expandir os arquivos pontuáveis, exceto .
e ..
.
peixe
fish
globs não incluem .
nem ..
. Quando não houver correspondência, dependendo da versão, funcionará como zsh
(ou bash -o failglob
) ou bash -o nullglob
.
mv -- * .* /dest/
Funcionaria se houvesse arquivos ocultos e não ocultos. Caso contrário, YMMV e com algumas versões, pode chamar mv -- /dest
se não houver nenhum arquivo.
ksh93
Nenhum qualificador de glob em ksh93
. Você pode incluir dotfiles em globs com:
FIGNORE='@(.|..)'
Ao contrário de bash
' GLOBIGNORE
, isso foi feito corretamente e também corrige o problema de .*
, incluindo .
e ..
.
yash
yash
tem uma opção dot-glob
( set -o dot-glob
), mas ao contrário de bash
, as expansões glob (mesmo de *
) incluem .
e ..
, por isso é bastante inútil.
tcsh
set globdot
Funciona como em bash
, ou seja, *
inclui arquivos de pontos, exceto .
e ..
, mas .*
ainda inclui .
e ..
(e você pode usar [.]*
para expandir ocultos arquivos, exceto .
e ..
).