Comment copier tous les dossiers contenant un fichier spécifique

17

Je souhaite sauvegarder uniquement mes dossiers de musique FLAC. Les fichiers FLAC peuvent être imbriqués comme ça dans les dossiers:

AlbumName/
├── Files/
│   ├── someSong01.flac
│   ├── someSong02.flac
├── Covers/
│   ├── someCover01.jpg
│   └── someCover02.jpg

Comment copier et déplacer tous les dossiers d'AlbumName avec leur structure et leur contenu correspondants qui contiennent quelque part dans au moins un fichier FLAC (je suppose que cela suffit pour dire: la musique est au format FLAC)

EDIT: les fichiers FLAC peuvent être imbriqués; donc 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

fricadelle
la source
sauvegarde où, quelle est votre destination?
George Udosen
Seuls les fichiers flac doivent-ils être copiés ou des dossiers entiers qui contiennent au moins un fichier flac?
personne
Dossiers @nobody: " Comment copier et déplacer tous les dossiers AlbumName avec leur structure et leur contenu correspondants qui contiennent quelque part dans au moins un fichier FLAC "
terdon

Réponses:

19

Une option consiste à utiliser rsync, qui copie uniquement les fichiers flac et préserve la structure du répertoire:

rsync -avzm --include=*/ --include=*.flac --exclude=* albums/ backup/
  • une archive
  • v verbeux
  • z compresser pendant le transfert (peut ne pas être utile de copier sur le même ordinateur)
  • m tailler les répertoires vides
  • comprend tout d'abord tous les répertoires
  • le second inclut les fichiers flac
  • la dernière exclusion exclut tous les autres fichiers
personne
la source
Vraiment? Je comprends, il veut préserver la structure du répertoire. Il dit: "Comment copier et déplacer tous les dossiers d'AlbumName avec leur structure et leur contenu correspondants ...".
personne
2
Oh je vois. Je ne suis pas sûr. Seuls les fichiers flac doivent-ils être copiés ou des dossiers entiers qui contiennent au moins un fichier flac?
personne
La question est éditée et maintenant elle explique plus en détail ce que veut fricadelle. Compte tenu du fait que tout le contenu doit être copié, s'il existe un fichier flac, ma réponse est fausse car il ne copie que les fichiers flac. Cependant, il peut encore être utile à d'autres fins.
personne
9

salut mon ami tu peux utiliser

mkdir newdirectory
cp -r --parents */*.flac newdirectory/
amir.m ghazanfari
la source
2
Nice jamais utilisé --parentsauparavant!
George Udosen
4
Veuillez expliquer cela */*.flac! Ne cp -r --parents AlbumName/ newdirectory/suffira pas?
George Udosen
3
D'après la question, il semble que les flacs puissent ou non être dans des répertoires imbriqués, donc je recommanderais d'activer globstar ( shopt -s globstar), puis d'utiliser **/*.flacpour le glob. La double étoile correspondra à zéro ou plusieurs répertoires.
wjandrea
vous avez exactement raison wjandrea, permettez-moi de modifier ma question pour que tout le monde comprenne
fricadelle
5

Belles réponses

Je veux ajouter une autre façon, vous pouvez également utiliser une combinaison de find et 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 passe-copie: 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 utilisez l'expression régulière 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-répertoires' Create leading directories where needed.'
  • --quiet' N'imprimez pas 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 également utiliser rsyncou écrire un script shell pour rechercher et copier des fichiers avec la structure de répertoires.

Pour l'explication de Rsync, veuillez consulter les réponses ci-dessus.

bsdboy
la source
2
Vous pouvez améliorer votre réponse en incluant des explications sur les commandes et les options que vous proposez. - De l'avis
J. Starnes
@dessert ouais, c'est ça. Merci pour votre suggestion parfaite.
bsdboy
4

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

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

Explication:

mkdircrée un nouveau répertoire. findLa commande recherche les *.flacfichiers situés dans le AlbumNamedossier. execcommande exécute la cpcommande pour chacun des noms de fichiers findrenvoyés.

Réponse 2: Vous pouvez également utiliser la findcommande avec xargsaussi bien

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

Plus d'informations: trouver , xargs

mf_starboi_8041
la source
1
find | xargsva casser sur les noms de fichiers avec des espaces, utilisez plutôt à la find -print0 | xargs -0place.
dessert
j'ai essayé avec un 1 2.flacfichier qui a de l'espace dans le nom de fichier. Pouvez-vous me faire savoir le nom du fichier sur lequel find | xargséchoue?
mf_starboi_8041
voir par exemple ici
dessert
Je ne sais pas mais je suis capable de copier un fichier avec un nom long qui contient de l'espace sans utiliser defind -print0 | xargs -0
mf_starboi_8041
Essayez touch "a space" && find . | xargs ls.
dessert
0

Je viens de résoudre le même problème pour ma bibliothèque musicale et je l'ai résolu en utilisant le script adapté suivant. Je ne l'ai pas entièrement conçu avec des variables ie, 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 à l'aide de rsync. rsync vous permet de reprendre le script s'il s'arrête pendant le processus.

Ma structure de bibliothèque:

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

Nouvelle structure de bibliothèque:

library
|-artist
  |- album 1 (mp3)

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

(1) démarrer le script shell suivant dans la destination SOURCE (remplacer TARGET par le répertoire respectif de votre choix - je viens d'utiliser le chemin absolu)

ligne 1: recherchez tous les répertoires contenant des fichiers flac et le canal (|) qui les trient
ligne 2: supprimez les doublons avec le tri et le canal qui figurent dans la boucle do
ligne 3: pour chaque répertoire faites la
ligne 4: affichez le répertoire dans le processus
ligne 5: rsync vers le répertoire cible plus supprimer la source et conserver la structure (-R) dans la
ligne d' emplacement cible 6: supprimer le répertoire vide (car rsync supprime uniquement 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 réussi à exécuter 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 tous les répertoires vides non supprimés dans le script. C'est-à-dire les répertoires "Artist", où tous les sous-dossiers / albums incluaient des fichiers flac.

wundabua
la source