Bash - Déplace de manière récursive tous les fichiers des dossiers portant le même nom dans leur répertoire parent


0

J'ai une bibliothèque de documents où tous mes fichiers se trouvent dans des dossiers basés sur le nom de la catégorie, mais ils se trouvent également dans des sous-dossiers appelés "pdf". Existe-t-il un moyen dans bash de parcourir tous les répertoires de la bibliothèque et de déplacer tous les fichiers des dossiers nommés pdf dans leur répertoire parent?

Réponses:


2

Ce qui suit déplace chaque fichier d’un pdfdossier vers le répertoire parent.

find ~/some/folder -type d -name 'pdf' -print0 | while IFS= read -d '' dir
do
  find "$dir" -type f -maxdepth 1 -exec echo mv -- {} "$dir"/.. \;
done

Supprimez-le echoune fois que vous êtes certain qu'il répond à vos besoins.

Notez que cela écrasera les fichiers sans demander quand le parent en contient déjà un du même nom. Utilisez-le mv -ipour qu'il vous invite à confirmer avant d'écraser quoi que ce soit.


De rien. Depuis que vous avez demandé des tutoriels sur Bash: Il existe des problèmes courants , ainsi que des pièges , à la fois sur le wiki de Bash de Greg - une très bonne ressource. Consultez également le Wiki Bash Hackers et le Guide de script avancé Bash
— slhck

1

Voici ce à quoi je pensais. Ce n'est pas la plus jolie chose, mais cela fonctionne selon vos spécifications:

find . -ipath "*pdf/*.pdf" -type f -print0 | xargs -0 -I{} sh -c 'mv "{}" "$(dirname "{}")"/..'

Il déplace uniquement les .pdffichiers des sous- pdfdossiers dans les répertoires parent correspondants. Pour modifier la commande afin de déplacer tous les fichiers des sous- pdfdossiers, ajustez l' ipathargument en *pdf/*.


Exemple d'utilisation

$ find .
.
./category1
./category1/other_dir
./category1/other_dir/c1o1.txt
./category1/pdf
./category1/pdf/c1p1.pdf
./category1/pdf/c1p2.pdf
./category1/pdf/c1p3.pdf
./category2
./category2/other_dir
./category2/other_dir/c2o1.txt
./category2/pdf
./category2/pdf/c2p1.pdf
./category2/pdf/c2p2.pdf
./category2/pdf/c2p3.pdf

$ find . -ipath "*pdf/*.pdf" -type f -print0 | xargs -0 -I{} sh -c 'mv "{}" "$(dirname "{}")"/..'
.
./category1
./category1/c1p1.pdf
./category1/c1p2.pdf
./category1/c1p3.pdf
./category1/other_dir
./category1/other_dir/c1o1.txt
./category1/pdf
./category2
./category2/c2p1.pdf
./category2/c2p2.pdf
./category2/c2p3.pdf
./category2/other_dir
./category2/other_dir/c2o1.txt
./category2/pdf

2
Pour la tuyauterie de findà xargs, vous devriez utiliser find … -print0 | xargs -0 ….
— Slhck

@slhck Vous avez raison; Merci d'avoir fait remarquer cela. Je viens de mettre à jour ma réponse.
— Rain

Belle avec le ipath, je n'ai pas pensé à ça. $(dirname $(dirname {}))peut être abrégé "$(dirname {})"/..si je ne me trompe pas. (En général, les arguments {}devraient être cités pour empêcher les fichiers comportant des espaces dans leur nom ou similaires de s'afficher sous forme d'arguments multiples mv.)
— slhck

Oui, je viens de le tester. ça fonctionne bien. "$(dirname {})"/..le rend beaucoup plus propre, aussi. Je n'ai même pas pensé à le citer, non plus. Tout chemin avec des espaces briserait la commande d'origine.
— Pluie

Vous pensez DOS. Sous Unix (et al.), *.*Récupère (uniquement) tous les fichiers dont le nom contient un point . Pour obtenir tous les fichiers, utilisez tout simplement *(et même cela pourrait ne pas avoir les fichiers dont le nom commence par un point).
— Scott
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.