La commande que vous recherchez est
mv * .[^.]* ..
ou (voir ci-dessous pour plus d'informations):
(shopt -s dotglob; mv -- * ..)
Explication :le mv
La commande déplace les fichiers et les répertoires. Le dernier argument de mv
est la cible (dans ce cas, le répertoire d'un niveau "en haut" dans l'arborescence, ..
). Les arguments avant cela sont les fichiers source et les répertoires. L'astérisque (*
) est un caractère générique qui correspond à tous les fichiers qui ne commencent pas par un point. Les fichiers qui commencent par un point (dotfiles) sont "cachés". Ils sont appariés en utilisant le modèle .[^.]*
(voir modification ci-dessous).
Voir la page de manuel que j'ai liée pour plus d'informations sur mv
.
Pourquoi .[^.]*
au lieu de .*
?
Comme le souligne correctement Chris Johnsen :le modèle .*
correspond également à .
et ..
. Puisque vous ne voulez pas (et ne pouvez pas) les déplacer, il est préférable d'utiliser un modèle qui correspond à n'importe quel nom de fichier commençant par un point sauf ces deux . Le motif .[^.]*
fait exactement cela :il correspond à n'importe quel nom de fichier (1) commençant par un point (2) suivi d'un caractère qui n'est pas un point (3) suivi de zéro ou plusieurs caractères arbitraires.
Comme le souligne Paggas, nous devrions également ajouter le modèle .??*
afin de faire correspondre les fichiers commençant par deux points. Voir sa réponse pour une solution alternative en utilisant find
.
La réponse d'Arjan mentionne shopt
afin d'éviter tous ces problèmes avec les fichiers de points. Mais il y a toujours le problème avec les fichiers commençant par un tiret. Et cela nécessite trois commandes. Pourtant, j'aime l'idée. Je propose de l'utiliser comme ceci :
(shopt -s dotglob; mv -- * ..)
Cela exécute shopt
dans un sous-shell (donc pas de deuxième appel à shopt
requis) et utilise --
afin que les fichiers commençant par un tiret ne soient pas interprétés comme des arguments de mv
.
Réponse courte :utilisez
find . -mindepth 1 -maxdepth 1 -exec mv -t.. -- {} +
Réponse longue :
La commande
mv * .* ..
ne fonctionnera pas depuis .*
peut correspondre à .
et ..
. Mais la commande
mv * .[^.]* ..
ne fonctionnera pas non plus, puisque .[^.]*
ne correspondra pas, par exemple, ..filename
! Au lieu de cela, ce que je fais est
mv * .[^.] .??* ..
qui correspondra à tout sauf .
et ..
. *
correspondra à tout ce qui ne commence pas par un .
, .[^.]
correspondra à tous les noms de fichiers à 2 caractères commençant par un point sauf ..
, et .??*
correspondra à tous les noms de fichiers commençant par un point avec au moins 3 caractères.
Mieux encore, vous pouvez utiliser
find . -mindepth 1 -maxdepth 1 -exec mv -t.. -- {} +
ce qui évite les vilains hacks glob en mv * .[^.] .??* ..
!
Juste pour être complet, on peut aussi dire au shell Bash d'inclure des fichiers cachés, en utilisant shopt
:
shopt -s dotglob
mv -- * ..
shopt -u dotglob