186 votes

Comment faire pour que mv (ou le caractère générique *) déplace les fichiers cachés ?

Je suis en train de migrer mon répertoire personnel d'un ancien système vers un nouveau, et l'archive tarball que j'ai créée contient tout, y compris les fichiers cachés comme .bashrc. Cependant, lorsque je déplace le contenu de l'archive déballée (qui se trouve dans /tmp) vers mon nouveau répertoire personnel, les fichiers cachés ne sont pas copiés ( mv /tmp/home/rcook/* /home/rcook/ ). Comment puis-je faire en sorte que mv les déplace ?

En fait, je pense que le problème n'est pas avec mv, mais avec le globbing de bash. Si je fais ça :

mkdir a
mkdir b
touch a/.foo
touch a/bar
mv a/* b/
ls -a a/ b/

Je vois ça :

a/:
.  ..  .foo

b/:
.  ..  bar

a/.foo n'a pas bougé. Alors comment faire pour que le joker * trouve les fichiers cachés ?

Oui, je suppose que je pourrais décompresser l'archive directement dans mon répertoire personnel, mais l'archive se décompresse en home/rcook/... et je veux être sûr que j'écrase la nouvelle .bashrc etc. avec les anciennes versions personnalisées, et savoir comment trouver et déplacer les fichiers cachés est une compétence utile. Des suggestions ?


Certaines réponses suggèrent de faire quelque chose comme mv src/.* dest/ . Cependant, j'ai essayé cela sur mes répertoires de test et j'ai obtenu des erreurs. En commençant par :

rcook$ ls -a a/ b/
a/:
.  ..  bar  .foo

b/:
.  ..
rcook$ mv a/.* b/
mv: cannot move 'a/.' to 'b/.': Device or resource busy
mv: cannot remove 'a/..': Is a directory
rcook$ ls -a a/ b/
a/:
.  ..  bar

b/:
.  ..  .foo

Qu'est-ce que je fais de mal ?

195voto

Gilles Quenot Points 3005

Vous pouvez le faire :

shopt -s dotglob
mv /tmp/home/rcook/* /home/rcook/

Vous pouvez mettre

shopt -s dotglob

dans votre ~/.bashrc si vous voulez qu'elle soit la valeur par défaut.

Ver http://mywiki.wooledge.org/glob


Une autre approche consiste à copier les fichiers point :

mv /tmp/home/rcook/.[!.]* /home/rcook/

N'utilisez pas le modèle ..* car il correspond .. (pointeur vers le répertoire parent). S'il y a des fichiers dont le nom commence par deux points ( ..something ), utilisez également le modèle ..?* .

63voto

codebrewer Points 81

Dans vos ajouts, vous avez obtenu des erreurs mais le code a quand même fonctionné. La seule chose à ajouter est que vous lui avez dit seulement pour copier les fichiers de points. Essayez :

mv src/* src/.* dst/

Vous obtiendrez toujours des erreurs pour les entrées . et .., ce qui n'est pas grave. Mais le déménagement devrait réussir.

~/scratch [andrew] $ mv from/* from/.* to/
mv: cannot move ‘from/.’ to ‘to/.’: Device or resource busy
mv: cannot remove ‘from/..’: Is a directory
~/scratch [andrew] $ ls -a from/ to/
from/:
.  ..

to/:
.  ..  test  .test

17voto

Azamat Points 436

Si vous ls -l dans un répertoire, vous verrez . y .. parmi les fichiers listés. Donc, je pense que mv .* /dest prend en compte ces pointeurs. Essayez :

mv /tmp/home/rcook/{*,.[^.]*,..?*} /home/rcook/

ceci ignorera les pointeurs de répertoire actuels et parentaux.

Vous obtiendrez une erreur si l'un de ces trois modèles * , [^.]* o ..?* ne correspond à aucun fichier, vous ne devez donc inclure que ceux qui correspondent.

11voto

Drake Clarris Points 1031

Deux solutions possibles me viennent à l'esprit. La première est d'utiliser cp à la place avec son option récursive, copiant le répertoire courant vers la destination.

cp -Rp . /desired/directory

alors vous pouvez supprimer les fichiers sources dans le répertoire courant

Alternativement, si vous savez que les fichiers sont nommés de manière saine (pas d'espaces, de caractères génériques, de caractères non imprimables), vous pouvez faire quelque chose comme ceci

mv $(ls -A) /desired/directory

5voto

tcarv Points 51

Je sais que c'est vieux, mais il y a un moyen simple de le faire :

mv a/{.*,*} b/

Explication

C'est ce qu'on appelle expansion de l'armature . Dans ce cas, le Shell développe le chemin que vous donnez en concaténant la chaîne donnée avant les accolades (dans ce cas-ci a/ ) suivi de chaque variante donnée dans la liste entourée d'accolades. La liste des variations est composée de valeurs séparées par des virgules et, là encore, entourées d'accolades. Ainsi, dans ce cas, nous avons .* y * comme éléments, donc la liste doit être {.*,*} .

mv a/{.*,*} b/

L'expression ci-dessus peut être lue de la façon suivante : déplacer tous les fichiers commençant par un point ( .* ) ET tout autre élément ( * ) dans le a/ dans le répertoire b/ répertoire.

Plus de conseils

C'est très utile et peut être utilisé dans divers scénarios. Par exemple, imaginez que vous devez créer 100 fichiers avec le modèle d'appellation suivant : fichier1, fichier2, fichier3...fichier100. Vous pouvez facilement y parvenir en procédant comme suit

touch file{1..100}

Dans ce cas, vous pouvez voir un gamme a été donné. Vous pouvez le faire en séparant la première et la dernière valeur par deux points ( .. ).

Aller plus loin !

Je suis nouveau dans le monde Unix et, même en sachant que cela fonctionne en bash y zsh (les shells que j'ai utilisés jusqu'à présent), je ne peux pas garantir que cela fonctionnera dans n'importe quel Shell.

Vous pouvez en savoir plus sur expansions un globbing dans la documentation de votre Shell (en utilisant : man bash o man zshall pour bash et zsh respectivement).

J'espère que cela aidera les futurs lecteurs !

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X