J'ai une tonne de fichiers et de répertoires dans un sous-répertoire que je souhaite déplacer vers le répertoire parent. Il existe déjà certains fichiers et répertoires dans le répertoire cible qui doivent être remplacés. Les fichiers qui ne sont présents que dans la cible ne doivent pas être modifiés. Puis-je forcer mv
à le faire? Il (mv * ..
) Se plaint
mv: cannot move `xyz' to `../xyz': Directory not empty
Qu'est-ce que je rate?
Vous devrez les copier vers la destination puis supprimer la source, à l'aide des commandes cp -r * ..
suivi par rm -rf *
.
Je ne pense pas que vous puissiez "fusionner" des répertoires en utilisant mv
.
rsync
serait probablement une meilleure option ici. C'est aussi simple que rsync -a subdir/ ./
.
Mon arbre de test au format filename
: contents
:
./file1:root
./file2:root
./dir/file3:dir
./dir/file4:dir
./subdir/dir/file3:subdir
./subdir/file1:subdir
Exécution de rsync
:
$ rsync -a -v subdir/ ./
sending incremental file list
./
file1
dir/
dir/file3
Donne:
./file1:subdir
./file2:root
./dir/file3:subdir
./dir/file4:dir
./subdir/dir/file3:subdir
./subdir/file1:subdir
Et puis, pour émuler mv
, vous voudrez probablement supprimer le répertoire source:
$ rm -r subdir/
Donnant:
./file1:subdir
./file2:parent
./dir/file3:subdir
./dir/file4:dir
Si cela ne va pas, pouvez-vous fournir un exemple similaire (par exemple en utilisant mon arbre de test près du haut de cette réponse) avec le résultat souhaité?
rsync
peut supprimer la source après des copies avec le --remove-source-files
paramètre. Cela devrait être un moyen pratique de faire ce que vous souhaitez.
Du rsync man page
:
--remove-source-files sender removes synchronized files (non-dir)
Vous pouvez le faire avec cp
et rm
, mais sans copier l'énorme quantité de données que vous essayez (vraisemblablement) d'éviter de transférer. @mattdm y a fait allusion dans son commentaire , et ne réponse à une autre question a une discussion plus complète sur les différentes options.
cp -rlf source destination
rm -r source
Essentiellement, l'option -l
Pour la commande cp
crée des liens durs vers des fichiers plutôt que de copier leurs données dans de nouveaux fichiers.
Voici un script qui déplace les fichiers sous /path/to/source/root
au chemin correspondant sous /path/to/destination/root
.
Attention, code non testé.
export dest='/path/to/destination/root'
cd /path/to/source/root
find . -type d \( -exec sh -c '[ -d "$dest/$0" ]' {} \; -o \
-exec sh -c 'mv "$0" "$dest/$0"' {} \; -Prune \) \
-o -exec sh -c '
if ! [ -e "$dest/$0" ]; then
mv -f "$0" "$dest/$0";
fi
' {} \;
Ce fil existe depuis des années et se classe toujours n ° 1 sur Google, donc je voulais ajouter une autre méthode. Comment je fais habituellement cela: emballer le contenu de la sous-répertoire dans une archive tar, déplacer l'archive tar dans le répertoire parent, puis l'extraire avec le comportement par défaut --overwrite. Cela fait exactement ce que vous recherchez. Ensuite, vous pouvez supprimer votre sous-répertoire.
cd xyz
tar -cvzpf tmp.tar.gz *
mv tmp.tar.gz ../tmp.tar.gz
cd ..
tar -xvzpf tmp.tar.gz
rm -rf xyz
rm -f tmp.tar.gz
Si vous avez suffisamment de stockage, vous pouvez le faire de la manière suivante:
mv -bfv directory_1/* directory_2/ # all duplicate source files/directories
# will have ~ appended to them
find -name "*~" -delete # will recursively find and delete all files
# with ~ on the end
Assurez-vous qu'il n'y a pas de fichiers importants avec un ~ à la fin, mais s'il y en a, vous pouvez ajouter --suffix=whateveryouwant
au lieu de la valeur par défaut.