17 votes

Comment copier tous les dossiers qui contiennent un fichier spécifique ?

Je veux sauvegarder uniquement mes dossiers de musique FLAC. Les fichiers FLAC pourraient être imbriqués comme ça à l'intérieur des dossiers :

AlbumName/
 Files/
    someSong01.flac
    someSong02.flac
 Covers/
    someCover01.jpg
    someCover02.jpg

Comment puis-je copier et déplacer tous les dossiers de AlbumName avec leur structure et leur contenu correspondants qui contiennent quelque part à l'intérieur au moins un fichier FLAC (je suppose que c'est suffisant pour dire : la musique est au format FLAC)

EDIT : Fichiers FLAC pourrait être imbriqués ; ainsi je peux avoir :

AlbumName2/
 someSong01.flac
 someSong02.flac
 Covers/
    someCover01.jpg
|    someCover02.jpg

Et je veux copier ces dossiers avec tout leur contenu, pas seulement les fichiers FLAC, et les coller dans un autre répertoire.

Donc si j'ai aussi

AlbumName3/
 someSong01.mp3
 someSong02.mp3
 Covers/
    someCover01.jpg
|    someHiddenSong.flac

et

AlbumName4/
 Files/
    someSong01.mp3
    someSong02.mp3
 Covers/
    someCover01.jpg
    someCover02.jpg

Je veux cp récursivement dans un autre répertoire AlbumName, AlbumName2 et AlbumName3 mais pas AlbumName4.

EDIT : Aucune des réponses ne faisait vraiment ce que je voulais, alors j'ai fini par utiliser quelque chose comme ça :

 find -mindepth 2 -name '*.flac' -exec dirname {} \; | awk -F "/" '{print $2}' | sort -u | while read -r dirname; do cp -r "$dirname" "backup/"; done

en gros je liste tous les fichiers flac, je récupère le dossier racine en utilisant awk, je supprime les doublons et je fais ce que je veux

19voto

nobody Points 4092

Une option consiste à utiliser rsync, qui ne copie que les fichiers flac et préserve la structure des répertoires :

rsync -avzm --include=*/ --include=*.flac --exclude=* albums/ backup/
  • une archive
  • v verbeux
  • z compresser pendant le transfert (peut ne pas être utile pour copier sur le même ordinateur)
  • m élaguer les répertoires vides
  • first include inclut tous les répertoires
  • second include inclut les fichiers flac
  • la dernière exclusion exclut tous les autres fichiers

9voto

amir.m ghazanfari Points 315

Salut mon ami, tu peux utiliser

mkdir newdirectory
cp -r --parents */*.flac newdirectory/

5voto

bsdboy Points 84

Bonnes réponses

Je veux ajouter un autre moyen, vous pouvez aussi utiliser une combinaison de trouver y cpio

find . -name "*.flac" -print0|cpio --null -pdm destination/

Explication :

GNU find searches the directory tree rooted at each given file name by evaluating the given expression from left to right, according to the rules of precedence (see Operators), until the outcome is known (the left-hand side is false for AND operations, true for OR), at which point find moves on to the next file name.

GNU cpio is a tool for creating and extracting archives, or copying files from one place to another. It handles a number of cpio formats as well as reading and writing tar files.

Il existe 3 modes cpio :

  • Mode copie : In copy-out mode, cpio copies files into an archive. It reads a list of filenames, one per line, on the standard input, and writes the archive onto the standard output.

  • Mode copie : In copy-in mode, cpio copies files out of an archive or lists the archive contents. It reads the archive from the standard input.

  • Mode copie-pass : In copy-pass mode, cpio copies files from one directory tree to another, combining the copy-out and copy-in steps without actually using an archive. It reads the list of files to copy from the standard input; the directory into which it will copy them is given as a non-option argument.

Ici, nous utilisons le mode Copy-pass.

  • Options utilisées dans la commande ci-dessus :

trouver :

  • -name -> nom de fichier ou utiliser une expression rationnelle au lieu d'écrire le nom complet.

cpio :

  • -m, --preserve-modification-time'. Retain previous file modification times when creating files.
  • -p, --pass-through Run in copy-pass mode. see ``Copy-pass mode``.
  • -d, --make-directories'. Create leading directories where needed.'
  • --quiet' Ne pas imprimer le nombre de blocs copiés.``

New options are the "-print0" available with GNU find, combined with the "--null" option of cpio. These two options act together to send file names between find and cpio, even if special characters are embedded in the file names.

On peut aussi utiliser rsync ou écrire un Shell Shell pour trouver et copier les fichiers avec la structure du répertoire.

Pour les explications concernant Rsync, veuillez consulter les réponses ci-dessus.

4voto

mf_starboi_8041 Points 143

Réponse 1 : Vous pouvez également utiliser find pour la même chose.

mkdir newDir && find AlbumName/ -iname "*.flac" -exec cp --parents "{}" newDir/ \;

Explication :

mkdir crée un nouveau répertoire. find La commande trouve *.flac situés dans AlbumName dossier. exec La commande exécute cp à chacun des noms de fichiers que find est revenu.

Réponse 2 : Vous pouvez également utiliser find avec xargs également

mkdir newDir && find AlbumName/ -iname "*.flac" | xargs -I{} cp --parents {} newDir/

Plus d'informations : trouver , xargs

0voto

Miro Points 186

J'ai juste eu à résoudre le même problème pour ma bibliothèque musicale et l'ai résolu en utilisant le script adapté suivant. Je ne l'ai pas entièrement conçu avec des variables, car je n'ai l'intention de l'utiliser qu'une seule fois :).

Le script déplace chaque répertoire contenant des fichiers flac, y compris tous les autres fichiers et sous-répertoires, vers un nouvel emplacement en utilisant rsync. rsync vous permet de reprendre le script s'il s'arrête pendant le processus.

La structure de ma bibliothèque :

library
|-artist
  |- album 1 (mp3)
  |- album 2 (flac)

Nouvelle structure de la bibliothèque :

library
|-artist
  |- album 1 (mp3)

library-lossless
|-artist
  |- album 2 (flac)

(1) lancer le Shell Shell suivant dans la destination SOURCE (remplacer TARGET par le répertoire respectif de votre choix - j'ai juste utilisé le chemin absolu)

ligne 1 : trouver tous les répertoires contenant des fichiers flac et mettre (|) dans le tri.
ligne 2 : supprimer les doublons avec le tri et envoyer cette liste dans la boucle do.
ligne 3 : pour chaque répertoire, faire
ligne 4 : montrer le répertoire en cours
ligne 5 : rsync vers le répertoire cible plus suppression de la source et préservation de la structure (-R) dans l'emplacement cible
ligne 6 : supprimer le répertoire vide (car rsync ne supprime que les fichiers)

find . -type f -name \*.flac -printf "%h\n" | 
sort -u | 
while read -r dirname; do
    echo $dirname
    rsync -azvm -R --remove-source-files "${dirname}" TARGET
    find "${dirname}" -type d -delete
done

(2) après avoir exécuté avec succès le script dans (1) vous pouvez exécuter la commande suivante dans le répertoire source

find . -depth -type d -empty -delete

Cette commande supprime toutes les vide les répertoires non supprimés dans le script. C'est-à-dire les répertoires "Artist", où tous les sous-dossiers/albums comprenaient des fichiers flac.

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X