Réponses:
Avertissement: Cette réponse traite spécifiquement de Bash, mais une grande partie s'applique à la question concernant les modèles glob!
Le caractère étoile ( *
) est un caractère générique. Il y a un certain ensemble de caractères qu'il remplacera et le premier caractère étant un point ( .
) n'en fait pas partie. Ceci est un cas particulier du fait du fonctionnement des systèmes de fichiers Unix, les fichiers commençant par un point sont considérés comme "masqués". Cela signifie que les outils tels que cp
, ls
, etc. ne « voir » à moins que dit explicitement de le faire.
Créons d'abord quelques exemples de données.
$ mkdir .dotdir{1,2} regdir{1,2}
$ touch .dotfile{1,2} regfile{1..3}
Nous avons donc maintenant les éléments suivants:
$ tree -a
.
|-- .dotdir1
|-- .dotdir2
|-- .dotfile1
|-- .dotfile2
|-- regdir1
|-- regdir2
|-- regfile1
|-- regfile2
`-- regfile3
Jouons maintenant à quelques jeux. Vous pouvez utiliser la commande echo
pour lister ce que *
serait un caractère générique ( ) particulier pour une commande donnée comme ceci:
$ 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
Vous pouvez utiliser la commande shopt -s dotglob
pour modifier le comportement du *
afin que, en plus des fichiers comme regfile1
celui-ci, il corresponde également .dotfile1
.
extrait du bash
page de manuel
dotglob If set, bash includes filenames beginning with a `.' in the results
of pathname expansion.
Exemple:
$ shopt -s dotglob
$ echo *
.dotdir1 .dotdir2 .dotfile1 .dotfile2 regdir1 regdir2 regfile1 regfile2 regfile3
Vous pouvez annuler ce comportement avec cette commande:
$ shopt -u dotglob
$ echo *
regdir1 regdir2 regfile1 regfile2 regfile3
Pour vous, vous dites cp
que vous souhaitez copier tous les fichiers qui correspondent au modèle *
, et il n'y a pas de fichiers.
$ cp foo/.* .
Ou vous pouvez le faire si vous voulez que tout soit dans le foo
dossier:
$ cp foo .
Ou vous pouvez être explicite:
$ cp foot/.* foo/* .
Une forme plus compacte utilisant l'expansion d'accolade dans bash
:
$ cp foo/{.,}* .
À tout moment, vous pouvez utiliser l' echo
astuce pour voir quels sont vos modèles de fichiers proposés (c'est le terme de fantaisie pour lequel l'étoile fait partie).
$ echo {.,}*
. .. .dotdir1 .dotdir2 .dotfile1 .dotfile2 abc regdir1 regdir2 regfile1 regfile2 regfile3
Soit dit en passant, si vous allez copier un répertoire de fichiers + d'autres répertoires, vous voulez généralement le faire récursivement, c'est le -R
passage à cp
:
$ cp -R foo/. .
shopt -s dotglob
, echo *
puis donne:.dotdir1 .dotdir2 .dotfile1 .dotfile2 regdir1 regdir2 regfile1 regfile2 regfile3
cp -r foo .
ne fonctionnera généralement pas car cp
refusera de se recopier foo
sur lui-même, vous vouliez probablement dire cp -R foo/. .
. (notez que cp -R
c'est le standard).
zsh
n'inclut pas .
et ..
dans l'expansion de .*
. Dans zsh
, si un modèle ne correspond pas, la commande est abandonnée (de manière assez sensible à nouveau), donc dans le cas général, cp foo/{,.}* .
échouera s'il n'y a pas de fichiers cachés ou non cachés.
shopt
n'existe pas.
Avec zsh
, la manière typique est d'utiliser le D
qualificatif glob (pour inclure les fichiers [D] ot):
cp foo/*(D) .
Notez qu'avec ou sans D
, les globes zsh n'incluent jamais .
ni ..
(comme vous vous en doutez).
Si ce que vous voulez faire est de copier tous les fichiers et répertoires d'un endroit à un autre, vous pouvez utiliser la rsync
commande standard . Dans l'exemple que vous donnez ci-dessus:
mkdir foo && touch foo/.test
rsync -a foo/ .
copiera récursivement tout le contenu de foo
, y compris les fichiers cachés et les répertoires cachés, dans le répertoire courant. La barre oblique de fin à la fin de foo/
est importante pour rsync; avec elle, seul le contenu de foo
est copié, sans cela rsync copiera foo
également. Par exemple:-
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'
Il existe de nombreuses autres options disponibles pour modifier rsync, y compris la copie entre machines.
dotglob
est traduitglobdots
par par zsh qui est un nom d'option non valide pour bash .