Comment déplacer tous les fichiers, y compris les fichiers cachés dans le répertoire parent via *

113

Ce doit être une question populaire mais je n'ai pas trouvé de réponse.

Comment déplacer tous les fichiers via *, y compris les fichiers cachés, vers le répertoire parent comme ceci:

mv /path/subfolder/* /path/

Cela déplacera tous les fichiers vers le répertoire parent comme prévu mais ne déplacera pas les fichiers cachés. Comment faire ça?

TroodoN-Mike
la source
1
cette question a un doublon chez SU , avec une réponse encore plus correcte (pas celle acceptée cependant): cp -r /path/to/source/. /destination
Florian

Réponses:

202

Vous pouvez trouver un ensemble complet de solutions à ce sujet dans la réponse d'UNIX et Linux à Comment déplacer tous les fichiers (y compris cachés) d'un répertoire à un autre? . Il montre des solutions dans Bash, zsh, ksh93, standard (POSIX) sh, etc.


Vous pouvez utiliser ces deux commandes ensemble:

mv /path/subfolder/* /path/   # your current approach
mv /path/subfolder/.* /path/  # this one for hidden files

Ou tous ensemble ( merci pfnuesel ):

mv /path/subfolder/{.,}* /path/

Qui s'étend à:

mv /path/subfolder/* /path/subfolder/.* /path/

(exemple: se echo a{.,}bdéveloppe en a.b ab)

Notez que cela affichera quelques avertissements:

mv: cannot move ‘/path/subfolder/.’ to /path/.’: Device or resource busy
mv: cannot remove /path/subfolder/..’: Is a directory

Ignorez-les simplement: cela se produit parce que /path/subfolder/{.,}*se développe également vers /path/subfolder/.et /path/subfolder/.., qui sont le répertoire et le répertoire parent (voir Que signifient «.» Et «..» dans un dossier? ).


Si vous souhaitez simplement copier, vous pouvez utiliser un simple:

cp -r /path/subfolder/. /path/
#                     ^
#                     note the dot!

Cela copiera tous les fichiers, normaux et cachés, car se /path/subfolder/.développe en "tout de ce répertoire" (Source: Comment copier avec cp pour inclure les fichiers cachés et les répertoires cachés et leur contenu? )

fedorqui 'Alors arrêtez de nuire'
la source
2
Les accolades ne sont qu'un raccourci mv /path/subfolder/* /path/subfolder/.* /path/, pas strictement nécessaire pour combiner les deux commandes en une seule.
chepner
7
J'obtiens l'erreur suivante:mv: overwrite `/path/.'? y mv: cannot move `/path/subfolder/.' to `/path/.': Device or resource busy mv: overwrite `/path/..'? y mv: cannot move `/path/subfolder/..' to `/path/..': Device or resource busy
Dejan
@Dejan Ignorez-le. .indique le répertoire courant et ..désigne le uprépertoire. Vous devez avoir remarqué que tous les autres fichiers sont déplacés.
Debiprasad
Il convient de mentionner que le raccourci d'accolades ne fonctionnera pas pour tous les shells, mais la commande @chepner je pense que ce sera le cas
Jesús Carrera
7
"Ignorer simplement l'avertissement" n'est pas toujours une bonne idée. En ce moment, j'ai un problème avec un script dans lequel je dois arrêter l'exécution si une étape échoue - puisque cette solution provoque toujours une erreur, elle tue mon script. J'ai besoin d'un moyen de déterminer si la commande mv a échoué ou non ...
MarioVilas
29

Je pense que c'est le plus élégant, car il n'essaye pas non plus de bouger ..:

mv /source/path/{.[!.],}* /destination/path
Vanderstaaij
la source
1
ouais je l'ai remarqué donnant aussi ces messages d'erreur, belle trouvaille.
Joseph Astrahan
Je pense que c'est une très bonne solution, mais il est un peu difficile de se souvenir de ce modèle
Dylan B
cela manquerait des fichiers comme ..anythingou ...anythingetc. - stackoverflow.com/a/31438355/2351568 contient le regex correct pour ce problème. || mais de toute façon utiliser shopt -s dotglobreste la meilleure solution!
DJCrashdummy
@DylanB ne le mémorise pas. rappelez-vous qu'il correspond à tout ce qui se trouve dans les accolades, séparés par des virgules. {a,b}*trouverait tous les fichiers commençant par a ou b tels que «anatomie» et «bulldozer». La deuxième correspondance est juste une correspondance vide, équivalente à *, et la première correspondance est équivalente à .[!.], où le groupe [!.]signifie un groupe ne commençant PAS par a .. Cela signifie .*mais pas ..*.
mazunki le
28

Cela déplacera tous les fichiers vers le répertoire parent comme prévu mais ne déplacera pas les fichiers cachés. Comment faire ça?

Vous pouvez activer dotglob:

shopt -s dotglob               # This would cause mv below to match hidden files
mv /path/subfolder/* /path/

Pour désactiver dotglob, vous devez dire:

shopt -u dotglob
devnull
la source
Très utile. Je voulais en savoir plus, mais shopt est intégré, donc man shoptne fonctionne pas et help shoptest très bref. Mais vous pouvez faire bashman () { man bash | less -p "^ $1 "; }et ensuite bashman shopttout lire à ce sujet directement. (Vous devrez peut-être appuyer sur n pour passer à la commande s'il y a des lignes commençant par shopt, comme je l'ai trouvé.)
Nick Rice
2
cela affectera également toutes les autres commandes comme ls.. donc pas vraiment ce que vous voudriez, probablement
phil294
5

Une autre solution plus simple consiste à utiliser l' rsyncutilitaire:

sudo rsync -vuar --delete-after --dry-run path/subfolder/ path/

Remarque: la commande ci-dessus montrera ce qui va être changé. Pour exécuter les modifications réelles, supprimez--dry-run .

L'avantage est que le dossier d'origine ( subfolder) serait supprimé ainsi qu'une partie de la commande, et lors de l'utilisationmv exemples ici, vous devez toujours nettoyer vos dossiers, sans parler de maux de tête supplémentaires pour couvrir les fichiers cachés et non cachés en un seul modèle.

en outre rsync charge la copie / déplacement de fichiers entre les télécommandes et garantit que les fichiers sont copiés exactement comme ils l'étaient à l'origine ( -a).

Le -uparamètre utilisé ignorerait les nouveaux fichiers existants, -rrentrerait dans les répertoires et -vaugmenterait la verbosité.

Kenorb
la source
La meilleure solution jamais! Dans mon cas, je viens de supprimer le paramètre -u, car je ne voudrais pas mettre à jour le dossier racine. Merci
Thales Ceolin
C'est l'une de ces commandes où si vous ne faites pas attention, vous pouvez vraiment gâcher les choses pour vous-même sous Linux, de manière permanente. Veuillez mettre à jour votre réponse pour inclure sudo avant la commande rsync, sinon, les utilisateurs peuvent facilement obtenir l'autorisation refusée pour mkdir, mais les suppressions de fichiers continueront néanmoins, ainsi, la commande rsync supprimera tout le répertoire que vous souhaitez déplacer, et ne fera rien d'autre . Vous perdrez tout votre répertoire. Une fois que vous avez ajouté sudo à votre réponse, cela devrait probablement être la réponse acceptée. La commande devrait donc être: sudo rsync -vuar --delete-after path / subfolder / path /
Blue Water
@JohnnyB Désolé pour la gêne occasionnée. J'ai ajouté sudoet --dry-run, afin que les gens puissent tester les modifications avant d'exécuter la commande réelle afin d'éviter tout désordre potentiel.
kenorb le
Oh, je ne savais pas qu'il y avait une option - à sec. Bon ajout. Pas besoin d'excuses. C'est excellent.
Blue Water
3

Laissez-moi vous présenter mon ami "dotglob". Il s'active et se désactive que "*" inclue ou non des fichiers cachés.

$ mkdir test
$ cd test
$ touch a b c .hidden .hi .den
$ ls -a
. ..  .den  .hi .hidden a b c

$ shopt -u dotglob
$ ls *
a b c
$ for i in * ; do echo I found: $i ; done
I found: a
I found: b
I found: c

$ shopt -s dotglob
$ ls *
.den  .hi .hidden a b c
$ for i in * ; do echo I found: $i ; done
I found: .den
I found: .hi
I found: .hidden
I found: a
I found: b
I found: c

Il est réglé par défaut sur "off".

$ shopt dotglob
dotglob         off

Il est préférable de le réactiver lorsque vous avez terminé, sinon vous risquez de confondre les choses qui supposent qu'il sera éteint.

TomOnTime
la source
3

En utilisant la findcommande en conjonction avec la mvcommande, vous pouvez empêcher la mvcommande d'essayer de déplacer des répertoires (par exemple ..et .) et des sous-répertoires. Voici une option:

find /path/subfolder -maxdepth 1 -type f -name '*' -exec mv -n {} /path \;

Il y a des problèmes avec certaines des autres réponses fournies. Par exemple, chacun des éléments suivants essaiera de déplacer les sous-répertoires du chemin source:

1) mv /path/subfolder/* /path/ ; mv /path/subfolder/.* /path/
2) mv /path/subfolder/{.,}* /path/ 
3) mv /source/path/{.[!.],}* /destination/path

En outre, 2) comprend le. et .. fichiers et 3) manque des fichiers comme ..foobar, ... barfoo, etc.

Vous pouvez utiliser mv /source/path/{.[!.],..?,}* /destination/path,, qui inclurait les fichiers manqués par 3), mais il essaierait toujours de déplacer les sous-répertoires. L'utilisation de la findcommande avec la mvcommande comme je l'ai décrit ci-dessus élimine tous ces problèmes.

teancum144
la source
2

Ma solution à ce problème lorsque je dois copier tous les fichiers (y compris les .fichiers) dans un répertoire cible en conservant les autorisations est: (écraser s'il existe déjà)

yes | cp -rvp /source/directory /destination/directory/

yesest pour écraser automatiquement les fichiers de destination, rrécursifs, vverbeux, pconserver les autorisations.

Notez que le chemin source ne se termine pas par un/ (donc tous les fichiers / répertoire et. Fichiers sont copiés)

Le répertoire de destination se termine par/ lorsque nous plaçons le contenu du dossier source vers la destination dans son ensemble.

Rajneesh Gadge
la source
While yesest une commande géniale à utiliser si vous souhaitez remplacer les fichiers de destination, ce n'est pas toujours souhaité. Utilisez-le uniquement si vous êtes sûr de vouloir le faire. De plus, y a-t-il une différence entre yes | cp ...et cp -f ...?
mazunki le