J'ai été surpris récemment quand j'ai fait quelque chose comme mv ./* ../somedirectory
et j'ai
constaté que les fichiers comme .gitignore
n'étaient pas déplacés.
Je fais la plupart de mon travail en zsh sur OS X, et cette surprise m'a mordu en bash sur CentOS. J'ai essayé bash sur OS X et j'ai trouvé le même comportement: *
ne correspond pas aux fichiers dot. Cela me semble très indésirable, mais apparemment c'est le bash par défaut. (C'est peut-être aussi la valeur par défaut de zsh pour tout ce dont je me souviens, mais je l'ai peut-être changé il y a des années dans mon .zshrc et j'ai oublié qu'il fonctionnait différemment.)
Comment puis-je configurer bash pour qu'il se comporte comme prévu: pour que * corresponde à tous les fichiers et n'ignore pas les fichiers dot.
Dans le cas où cela n'est pas clair du tout, voici comment le reproduire
cd /tmp
mkdir {t,d}est
touch test/{.,}{1,2,3,4,5,6,7}
ls -hal test
mv test/* dest
ls -hal test # notice dot files are still there
ls -hal dest # notice only some files were mv'ed
Réponses:
Frapper
Comme vous l'avez déjà remarqué, bash ne correspondra pas à un
.
au début du nom ni à une barre oblique. Pour modifier la correspondance concernant le point, vous devez définir l'dotglob
option - man bash :Pour l'activer / le définir avec l'utilisation bash
shopt
, par exemple:Pour zsh, vous pouvez également utiliser l'
dotglob
option mais mais vous devrez l'utilisersetopt
pour l'activer, par exemple:la source
zsh
, la meilleure option est d'activer dotglob par glob:mv test/*(D) /dest
J'ai testé cela et cela résout le problème:
Production:
la source
*
est un glob qui est développé par le shell. Par défaut, les shells n'incluent pas les fichiers dont le nom commence par un.
(appelé fichiers cachés ou fichiers dot) sauf si le début.
est entré littéralement.*
ou[.]*
ou?*
ou*.*
oudir/*
n'inclura pas les fichiers dot..*
ou ledir/.*
fera.Vous pourriez donc faire:
Cependant, certains shells, y compris
bash
(mais paszsh
,mksh
nifish
), ont cette erreur que l'expansion d'.*
inclure les entrées de répertoire spéciales.
et..
, que vous ne voulez pas ici (et généralement ne voulez jamais un glob à inclure, c'est pourquoi je l'appelle une erreur).Pour cette raison, vous constaterez que parfois les gens utilisent (dans des coquilles de type Bourne):
Il s'agit de trois globes, le premier correspondant aux fichiers non masqués, le second commençant par
.
suivi d'un caractère différent de.
et le troisième commençant par..
suivi d'au moins un caractère.Cependant, certains obus modernes ont de meilleurs moyens de contourner cela
zsh
Avec
zsh
, vous pouvez utiliser le(D)
qualificatif glob pour spécifier que le glob doit inclure des fichiers dot:zsh
a également corrigé cette autre erreur du shell Bourne en ce que si le modèle ne correspond pas, lamv
commande n'est pas exécutée.Comme dit ci-dessus, il n'inclura jamais
.
non plus..
dans ses globes, doncsera en sécurité. Cependant, s'il n'y a pas de correspondance de fichier
*
ou de fichier correspondant,.*
la commande sera abandonnée, il serait donc préférable d'utiliser:Comme dans certains autres shells, vous pouvez également forcer tous les globs à inclure des dotfiles (par exemple si vous vous retrouvez à vouloir des dotfiles inclus le plus souvent) avec:
ou:
Après cela, si vous souhaitez qu'un glob particulier n'inclue pas de fichiers dot, vous pouvez l'écrire:
Ou:
Frapper
Malheureusement, il
bash
n'y a pas de qualificatifs glob. Il vous reste donc à activer l'inclusion de fichiers dot à l'échelle mondiale. Dansbash
, la syntaxe est:(et utiliser
[^.]*
pour les globes sans fichiers cachés).Avec
dotglob
,bash
n'inclut pas.
ni..
dans les globes comme*
, mais le fait toujours pour les globes comme.*
.Si vous définissez la
GLOBIGNORE
variable sur quelque chose de non vide, elle active automatiquement l'dotglob
option et exclut.
et..
des.*
globs mais pas dedir/.*
ou.*/file
ceux (!) De sorte que la sauvegarde est assez inutile. Vous pourriez le faire,GLOBIGNORE='*/.:*/..:./*:../*:*/./*:*/../*'
mais cela briserait des globes comme*/.
ou./*
ou../*
.Une meilleure solution consiste à utiliser
[.]*
oudir/[.]*
ou[.]*/file
(avecdotglob
activé) pour développer les fichiers dot à l'exception de.
et..
.poisson
fish
les globes n'incluent pas.
ni..
. Lorsqu'il n'y a pas de correspondance, selon la version, cela fonctionnera commezsh
(oubash -o failglob
) oubash -o nullglob
.Fonctionnerait s'il y avait des fichiers cachés et non cachés. Sinon, YMMV et avec certaines versions, il peut appeler
mv -- /dest
s'il n'y a pas de fichier du tout.ksh93
Aucun qualificatif global dans les
ksh93
deux cas. Vous pouvez inclure des fichiers dot dans des globes avec:Contrairement à
bash
'sGLOBIGNORE
, cela se fait correctement et résout également le problème d'.*
inclusion de.
et..
.yash
yash
a unedot-glob
option (set -o dot-glob
), mais contrairement àbash
, les extensions globales (même de*
) incluent.
et..
donc c'est assez inutile.tcsh
Fonctionne comme dans
bash
, c'est-à-dire*
inclure les fichiers dot sauf.
et..
mais.*
inclut toujours.
et..
(et vous pouvez utiliser[.]*
pour développer les fichiers cachés sauf.
et..
).la source
La manière la plus simple en bash d'imprimer des fichiers de points correspondants, en ignorant
.
et..
c'est:Tester:
Il a imprimé tous les fichiers avec des points ou non, à l'exception notable de
.
et..
.Votre exemple fonctionnera également correctement:
Vide de fichiers importants.
Les fichiers système
.
..
existent toujours mais une extension shell (en utilisant *) ne les inclura pas.Et le répertoire de destination contient tous les fichiers:
Pourquoi?
Cela fonctionne car la configuration de GLOBIGNORE a ces effets secondaires:
shopt -s dotglob
) sur des fichiers de points mathématiques lors des extensions..
et..
sont ignorés lorsque GLOBIGNORE est défini et non nul.Détails dans le manuel:
LESS=+'/The GLOBIGNORE' man bash
.De plus, nous devons définir la variable GLOBIGNORE pour qu'elle contienne un nom auquel aucun nom de fichier ne pourrait correspondre:
une barre oblique (et autre chose juste à titre de double précaution).
Il peut être utile de définir également nullglob si cela est nécessaire pour éviter d'obtenir un
*
lorsqu'il n'y a pas de fichier correspondant au*
.la source
Très intéressé par ce paramètre de GLOBIGNORE = / + / @ user79743
D'après mon expérience MHS dotglob est une mauvaise affaire à presque toutes vos commandes (cp, mv , etc.) , mais la même chose est vraie mise la nullglob ( en particulier avec des expressions régulières qui ont besoin alors s'échapper!).
Néanmoins, si vous devez les définir au début de votre programme mais interférer dans des parties spécifiques où vous appelez des commandes comme cp, mv, etc. ou utilisez des expressions régulières, procédez comme suit:
la source