Comment déplacer de manière récursive tous les files (y compris cachés) dans un sous-dossier dans un dossier parent dans * nix?

C'est une question embarrassante, mais je dois admettre que, tard dans ma carrière, j'ai toujours des questions sur la command mv.

J'ai souvent ce problème: je dois déplacer tous les files récursivement d'un niveau. Disons que j'ai un dossier foo, et une barre de dossier à l'intérieur. Bar a un désastre de files et de dossiers, y compris les files de points et les dossiers. Comment déplacer tout en barre au niveau foo?

Si foo est vide, je déplace simplement la barre un niveau ci-dessus, supprimez foo et renommez la barre en foo. Une partie du problème est que je ne peux pas comprendre ce que le slider de mv pour "tout ce qui inclut les points" est. Une partie de cette question est la suivante: existe-t-il une discussion approfondie sur les caractères generics que les commands cp et mv utilisent quelque part (le googling, c'est seulement des tutoriels très basiques).

Dans Bash (et d'autres), vous pouvez utiliser l'extension de l'accolade pour l'accomplir en une seule ligne:

mv bar/{,.}* . 

La virgule sépare un null et un point, de sorte que la command mv voit les noms de files qui correspondent * et .*

La façon la plus simple de le faire est de le faire en deux commands, car * ne correspond pas. Quoi qu'il en soit

 cd /foo mv bar/* ./ mv bar/.??* ./ 

Vous ne souhaitez pas utiliser la barre /.* que j'ai découvert en commettant cette erreur:

 rm -rf ./.* 

Ceci est une mauvaise chose. Quelqu'un veut-il deviner pourquoi? 😉

La première chose à savoir sur le globbing – c'est fait par le shell, pas la command. Consultez la page man de votre shell pour tous les détails.

Celui-ci récolte tous les files des sous-dossiers et les déplace vers le directory actuel

 find . -type f -exec mv -iv \{} . \; 

Si vous souhaitez envoyer des files avec le même nom, utilisez

 yes y | find . -type f -exec mv -iv \{} . \; 

mv .??* * prendra soin de tout sauf le point suivi d'un seul personnage. Si cela est courant pour votre situation, vous pouvez append .[a-zA-Z0-9]* . Cela laissera toujours des files contenant des noms tels que .; , .^ , et .^I (onglet). Si vous devez gérer tout, vous devrez être un peu plus complexe.

 mv .. `ls -f | egrep -v '^.$|^..$' 

Si vous avez une structure de directory /foo/bar/ et que vous souhaitez déplacer tous les files sous la bar une étape ci-dessus, accédez au directory de la bar et tapez ce qui suit:

 find . -depth -print0 | cpio --null -pvd ../ 

Généralement, je pense que cpio(1) est mieux pour ce type de tâches. Vous pouvez consulter la documentation détaillée en publiant info cpio dans votre shell.