Comment puis-je obtenir mv (ou le caractère générique *) pour déplacer des fichiers cachés?

134

Je migre mon répertoire personnel d'un ancien système vers un nouveau et l'archive que j'ai créée contient tout, y compris des fichiers cachés tels que .bashrc. Cependant, lorsque je déplace le contenu de l'archive tar décompressée (qui se trouve dans / tmp) vers mon nouveau répertoire de base, les fichiers cachés ne sont pas copiés ( mv /tmp/home/rcook/* /home/rcook/). Comment puis-je obtenir pour les déplacer?

En fait, je pense que le problème ne vient pas de mv, mais 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/.foon'a pas bougé. Alors, comment puis-je obtenir le caractère générique * pour trouver des 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 m'assurer d'écraser les nouvelles .bashrc, etc. avec les anciennes versions personnalisées et savoir comment trouver et déplacer les fichiers cachés. est une compétence utile. Suggestions?


Certaines réponses suggèrent de faire quelque chose comme mv src/.* dest/. Cependant, j'ai essayé ceci sur mes répertoires de test et j'ai eu des erreurs. 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 mal?

Randall Cook
la source

Réponses:

147

Tu peux le faire :

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

Tu peux mettre

shopt -s dotglob

dans votre ~/.bashrcsi vous voulez que ce soit la valeur par défaut.

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


Une autre approche pour copier les fichiers de points:

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

N'utilisez pas le modèle ..*tel qu'il correspond ..(pointeur sur le répertoire parent). S'il existe des fichiers dont le nom commence par deux points ( ..something), utilisez également le modèle ..?*.

Gilles Quenot
la source
S'il vous plaît vérifier les ajouts que j'ai mis au bas de ma question. Merci.
Randall Cook
1
Rien ne va, .et ..sont des dirs spéciaux: respectivement dir actuel et dir parent . C'est juste un avertissement. Meilleure shopt -s dotglobsolution d' utilisation
Gilles Quenot le
J'ai fini par ne faire que deux mouvements: mv home/rcook/* /home/rcook/suivi de mv home/rcook/.* /home/rcook/. Cela a fait l'affaire, bien que j'aurais aimé suivre le lien et en savoir plus sur le mode pointglob. Cela m'aurait sauvé une étape. +1
Randall Cook
La seconde approche nécessite donc l’utilisation de chemins absolus?
Franzlorenzon
3
Si vous utilisez zsh, vous pouvez utiliser le Dqualificatif Globbing ou l' GLOB_DOTSoption shell .
mgalgs
43

Dans vos ajouts, vous avez des erreurs mais le code fonctionnait toujours. La seule chose à ajouter est que vous ne lui avez demandé que de copier les fichiers de points. Essayer:

mv src/* src/.* dst/

Vous aurez toujours les erreurs pour le fichier. et .. entrées, ce qui est bien. 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
Andrew Schwartz
la source
1
Bons points, AndrewSchwartz. J'aime cette approche aussi. Je pense que cela mérite plus de reconnaissance.
Randall Cook
J'aime bien que @Drake Clarris réponde un peu plus, car je suis sous Amazon AWS CodeBuild et que le code de retour non nul a effectivement entraîné l'arrêt de ma construction. J'ai fini par déplacer le .hiddenfichier que j'avais explicitement pour résoudre mon problème.
HeyWatchThis
Si le code de sortie différent de zéro pose un problème, vous pouvez le supprimer, par exemple en ajoutant || :(cela ||signifie que vous exécutez ce qui suit sur false / error, :c’est la commande noop). Mais cela supprimerait également les erreurs légitimes, par exemple le dossier de destination n’existe pas. Je ne trouve pas de méthode plus élégante mvpour exclure les entrées .et ... Mais le gros avantage pour moi sur cp n’est pas d’écrire de nouveaux fichiers sur le disque.
Andrew Schwartz
10

Si vous êtes ls -ldans un répertoire, vous verrez .et ..parmi les fichiers listés. Donc, je pense mv .* /destprend ces pointeurs en compte. Essayer:

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

cela ignorera les pointeurs de dir actuels et parents.

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

Azamat
la source
Agréable. Une réponse similaire pour ce style de globbing est la suivante: superuser.com/a/784046/144977 . Merci d'avoir posté ceci.
Phyatt
7

Deux solutions possibles auxquelles je peux penser. La première consiste à utiliser cp à la place avec son option récursive, en copiant le répertoire actuel dans la destination.

cp -Rp . /desired/directory

alors vous pouvez supprimer les fichiers source dans le répertoire en cours

Alternativement, si vous savez que les fichiers sont nommés proprement (sans espaces, caractères génériques, caractères non imprimables), vous pouvez faire quelque chose comme ceci.

mv $(ls -A) /desired/directory
Drake Clarris
la source
4
Copy-then-remove est très différent du déplacement si la source et la cible se trouvent sur le même système de fichiers. Incluez au moins l'option -pde préservation des métadonnées. L'utilisation lsdevrait être un dernier recours, et il existe ici des moyens plus simples et plus efficaces.
Gilles
2

Il n’existe pas vraiment de fichiers "cachés" sous Linux. Les fichiers commençant par un point sont simplement masqués des listes de fichiers par défaut.

Pour copier des fichiers même avec un glob, vous devez préfixer le fichier avec ., par exemple, mv -u .* fooet il .fooapparaîtra alors comme foo/.foos'il était déplacé.

L'option -u ne déplacera les fichiers que lorsque la source est plus récente ou que la destination est manquante. Ou vous pouvez simplement ignorer les erreurs concernant le déplacement ., ..car ce sont des fichiers spéciaux et ne peuvent pas être déplacés, mais ils sont pris dans le .*glob par le shell.

Dobey
la source
S'il vous plaît vérifier les ajouts que j'ai mis au bas de ma question. Merci.
Randall Cook
0

Nous avons donc:

a
|-- .foo
`-- bar

et:

b

J'ai mis beaucoup de temps à trouver une meilleure solution que toutes les réponses fournies ici.

Ensuite, j'ai pris 30 secondes pour cette commande:

$ mv --help

Puis j'ai retrouvé mon amour:

$ mv a/ b/ -T

Note: Je ne comprends même pas l'argument -T. Il a juste fait ce dont j'avais besoin. Ici on dit:

-T, --no-target-directory considère DEST comme un fichier normal

utilisateur433901
la source
1
Si vous omettez les barres obliques, vous ne devriez pas en avoir besoin -T. Quoi qu'il en soit, cela signifie essentiellement que mv doit déplacer le répertoire lui-même, plutôt que de déplacer tous les fichiers qu'il contient.
thomasrutter
@ thomasrutter, déplacer le répertoire lui-même ne revient-il pas à le renommer?
Randall Cook
3
Oui, si la destination parent reste la même, il s’agit essentiellement de la renommer. Cependant , vous faites référence, il n'aide probablement pas répondre à la question initiale, qui allait déplacer les fichiers dans le répertoire dans un endroit donné.
thomasrutter
0

Dans mon cas, je cherchais simplement mvun seul fichier caché et voici la solution:

FILE=.myHiddenFile
mv "$FILE" dest/

Explication

Au début j'essayais:

mv .myHiddenFile dest/

Mais cela continuait à produire l'erreur:

mv: cannot stat '.myHiddenFile': No such file or directory

Même si un a ls -almontré que le fichier et dest/existait.

La raison semble être que le shell interprétait le "." dans le nom du fichier, donc en le déplaçant vers une variable, il évite l'interprétation. Il existe probablement d'autres moyens de résoudre ce problème, mais cela nous suffisait.

Isaïe
la source
-1

Si vous souhaitez copier des fichiers, y compris des fichiers cachés, dans le répertoire actuel dans lequel vous vous trouvez.

cp -Rp source-directory/. .
Meule
la source
1
Cela ressemble beaucoup à la réponse de Drake Clarris de 2013. Avez-vous quelque chose à ajouter?
Randall Cook