So kopieren Sie alle Ordner, die eine bestimmte Datei enthalten

17

Ich möchte nur meine FLAC-Musikordner sichern. FLAC-Dateien könnten so in den Ordnern verschachtelt sein:

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

Wie kopiere und verschiebe ich alle Ordner von AlbumName mit der entsprechenden Struktur und dem entsprechenden Inhalt, die mindestens eine FLAC-Datei enthalten (ich gehe davon aus, dass dies ausreicht, um zu sagen: Die Musik ist im FLAC-Format)

BEARBEITEN: FLAC-Dateien könnten verschachtelt sein; also kann ich haben:

AlbumName2/
├── someSong01.flac
├── someSong02.flac
├── Covers/
│   ├── someCover01.jpg
|   └── someCover02.jpg

Und ich möchte diese Ordner mit all ihren Inhalten, nicht nur FLAC-Dateien, kopieren und in ein anderes Verzeichnis einfügen.

Also wenn ich das auch habe

AlbumName3/
├── someSong01.mp3
├── someSong02.mp3
├── Covers/
│   ├── someCover01.jpg
|   └── someHiddenSong.flac

und

AlbumName4/
├── Files/
│   ├── someSong01.mp3
│   ├── someSong02.mp3
├── Covers/
│   ├── someCover01.jpg
│   └── someCover02.jpg

Ich möchte rekursiv in ein anderes Verzeichnis cp AlbumName, AlbumName2 und AlbumName3 aber nicht AlbumName4

EDIT: Keine der Antworten hat wirklich getan, was ich wollte, also habe ich so etwas benutzt:

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

im grunde liste ich alle flac dateien auf, rufe den root ordner mit awk ab, lösche die duplikate und mache was ich will

Fricadelle
quelle
Backup wo, was ist dein Ziel?
George Udosen
Müssen nur Flac-Dateien kopiert werden oder ganze Ordner, die mindestens eine Flac-Datei enthalten?
Niemand
@nobody-Ordner: " Wie kopiere und verschiebe ich alle Ordner von AlbumName mit der entsprechenden Struktur und dem entsprechenden Inhalt , die mindestens eine FLAC-Datei enthalten "
terdon

Antworten:

19

Eine Option ist die Verwendung von rsync, das nur flac-Dateien kopiert und die Verzeichnisstruktur beibehält:

rsync -avzm --include=*/ --include=*.flac --exclude=* albums/ backup/
  • ein Archiv
  • v ausführlich
  • z Komprimieren während der Übertragung (Kopieren auf demselben Computer möglicherweise nicht sinnvoll)
  • m leere Verzeichnisse beschneiden
  • first include enthält alle Verzeichnisse
  • zweites include beinhaltet flac files
  • Der letzte Ausschluss schließt alle anderen Dateien aus
niemand
quelle
"Ja wirklich?" Ich verstehe, er will die Verzeichnisstruktur bewahren. Er sagt: "Wie kopiere und verschiebe ich alle Ordner von AlbumName mit der entsprechenden Struktur und dem entsprechenden Inhalt ...".
Niemand
2
Oh, ich verstehe. Ich bin mir nicht sicher. Müssen nur Flac-Dateien kopiert werden oder ganze Ordner, die mindestens eine Flac-Datei enthalten?
Niemand
Die Frage wird bearbeitet und erklärt nun genauer, was Fricadelle will. Berücksichtigt man, dass alle Inhalte kopiert werden sollen, wenn es eine flac-Datei gibt, ist meine Antwort falsch, da sie nur flac-Dateien kopiert. Es kann jedoch noch für einen anderen Zweck nützlich sein.
Niemand
9

Hallo mein Freund, den du benutzen kannst

mkdir newdirectory
cp -r --parents */*.flac newdirectory/
amir.m ghazanfari
quelle
2
Nizza noch nie benutzt --parents!
George Udosen
4
Bitte erläutern Sie dies */*.flac! Wird cp -r --parents AlbumName/ newdirectory/nicht ausreichen?
George Udosen
3
Aus der Frage ergibt sich, dass sich die Flacs möglicherweise in verschachtelten Verzeichnissen befinden oder nicht. Daher würde ich empfehlen, globstar ( shopt -s globstar) zu aktivieren und dann **/*.flacfür glob zu verwenden. Der Doppelstern stimmt mit keinem oder mehreren Verzeichnissen überein.
wjandrea
Sie sind genau richtig wjandrea, lassen Sie mich meine Frage so bearbeiten, dass jeder versteht
Fricadelle
5

Gute Antworten

Ich möchte noch eine Möglichkeit hinzufügen, Sie können auch eine Kombination aus find und cpio verwenden

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

Erläuterung:

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.

Es gibt 3 CPIO-Modi:

  • Kopiermodus: 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.

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

  • Copy-Pass-Modus: 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.

Hier verwenden wir den Copy-Pass-Modus.

  • Im obigen Befehl verwendete Optionen:

finden:

  • -name -> Dateiname oder verwenden Sie Regex, anstatt den vollständigen Namen zu schreiben

cpio:

  • '-m, --Modifikationszeit beibehalten' Retain previous file modification times when creating files.
  • '-p, - pass-through' Run in copy-pass mode. see ``Copy-pass mode``.
  • '-d, --make-directorys' Create leading directories where needed.'
  • --quiet' Drucken Sie nicht die Anzahl der kopierten Blöcke. "

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.

Man kann auch rsyncein Shell-Skript verwenden oder schreiben, um Dateien mit der Verzeichnisstruktur zu finden und zu kopieren.

Weitere Informationen zu Rsync finden Sie in den obigen Antworten.

bsdboy
quelle
2
Sie können Ihre Antwort verbessern, indem Sie Erklärungen zu den Befehlen und den von Ihnen vorgeschlagenen Optionen hinzufügen. - Aus der Bewertung
J. Starnes
@ Dessert ja, richtig. Vielen Dank für Ihren perfekten Vorschlag.
bsdboy
4

Antwort 1: Sie können auch den findBefehl dafür verwenden.

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

Erklärung:

mkdirErstellt ein neues Verzeichnis. findBefehl findet *.flacDateien im AlbumNameOrdner. execBefehl führt den cpBefehl für jeden zurückgegebenen Dateinamen aus find.

Antwort 2: Sie können auch verwenden findBefehl mit xargsals auch

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

Weitere Informationen: find , xargs

mf_starboi_8041
quelle
1
find | xargswird bei Dateinamen mit Leerzeichen aufbrechen, stattdessen verwenden find -print0 | xargs -0.
Dessert
Ich habe es mit einer 1 2.flacDatei versucht , die Platz im Dateinamen hat. Können Sie mir bitte den Dateinamen mitteilen, bei dem ein find | xargsFehler auftritt?
mf_starboi_8041
siehe zB hier
Dessert
Ich weiß es nicht, aber ich kann Dateien mit langen Namen, in denen Platz ist, ohne Verwendung von find -print0 | xargs -0
kopieren
Versuchen Sie es touch "a space" && find . | xargs ls.
Dessert
0

Hatte gerade das gleiche Problem für meine Musikbibliothek zu lösen und löste es mit dem folgenden angepassten Skript. Ich habe es nicht vollständig mit zB Variablen erstellt, da ich es nur einmal verwenden möchte :).

Das Skript verschiebt jedes Verzeichnis mit flac-Dateien einschließlich aller anderen Dateien und Unterverzeichnisse mit rsync an einen neuen Speicherort. Mit rsync können Sie das Skript fortsetzen, wenn es während des Vorgangs angehalten wird.

Meine Bibliotheksstruktur:

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

Neue Bibliotheksstruktur:

library
|-artist
  |- album 1 (mp3)

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

(1) Starten Sie das folgende Shell-Skript im SOURCE-Ziel (ersetzen Sie TARGET durch das entsprechende Verzeichnis Ihrer Wahl - ich habe nur den absoluten Pfad verwendet)

Zeile 1: Finden Sie alle Verzeichnisse FLAC - Dateien und Rohr , die (|) , die in Art
Zeile 2: Entfernen Sie Duplikate mit Art und Rohr , dass die Liste in die do - Schleife
Zeile 3: für jedes Verzeichnis tut
Zeile 4: zeigen Sie das Verzeichnis in der Prozessreihe
5: Rsync in das Zielverzeichnis sowie Entfernen der Quelle und Beibehalten der Struktur (-R) in
Zeile 6 des Zielverzeichnisses : Leeres Verzeichnis entfernen (da Rsync nur Dateien entfernt)

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) Nach erfolgreicher Ausführung des Skripts in (1) können Sie den folgenden Befehl im Quellverzeichnis ausführen

find . -depth -type d -empty -delete

Dieser Befehl löscht alle leeren Verzeichnisse, die nicht im Skript gelöscht wurden. Dh "Artist" -Verzeichnisse, in denen alle Unterordner / Alben flac-Dateien enthalten.

Wundabua
quelle