Cara menyalin semua folder yang berisi file tertentu

17

Saya ingin mencadangkan hanya folder musik FLAC saya. File FLAC dapat disarangkan seperti itu di dalam folder:

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

Bagaimana cara menyalin dan memindahkan semua folder AlbumName dengan struktur dan konten yang sesuai yang mengandung suatu tempat di dalam setidaknya satu file FLAC (saya akan menganggap ini cukup untuk mengatakan: musik dalam format FLAC)

Sunting: File FLAC bisa diulang; jadi saya dapat memiliki:

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

Dan saya ingin menyalin folder-folder itu dengan semua isinya, bukan hanya file FLAC, dan rekatkan ke direktori lain.

Jadi kalau saya punya juga

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

dan

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

Saya ingin cp secara rekursif ke direktori lain AlbumName, AlbumName2 dan AlbumName3 tetapi tidak AlbumName4

EDIT: Tidak ada jawaban yang benar-benar melakukan apa yang saya inginkan, jadi saya akhirnya menggunakan sesuatu seperti itu:

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

pada dasarnya saya daftar semua file flac, saya mengambil folder root menggunakan awk, saya menghapus duplikat dan saya melakukan apa yang saya inginkan

fricadelle
sumber
backup ke mana, apa tujuan Anda?
George Udosen
Apakah hanya file flac yang perlu disalin atau seluruh folder yang memiliki setidaknya satu file flac?
tidak ada yang
@nobody folder: " Bagaimana cara saya menyalin dan memindahkan semua folder AlbumName dengan struktur dan konten terkait yang mengandung suatu tempat di dalam setidaknya satu file FLAC "
terdon

Jawaban:

19

Opsi adalah menggunakan rsync, yang hanya menyalin file flac dan mempertahankan struktur direktori:

rsync -avzm --include=*/ --include=*.flac --exclude=* albums/ backup/
  • arsip
  • v verbose
  • z kompres saat transfer (mungkin tidak berguna menyalin pada komputer yang sama)
  • m memangkas dir kosong
  • pertama-tama termasuk semua direktori
  • kedua termasuk file flac
  • mengecualikan terakhir mengecualikan semua file lainnya
tak seorangpun
sumber
Betulkah? Saya mengerti, dia ingin mempertahankan struktur direktori. Dia mengatakan: "Bagaimana cara saya menyalin dan memindahkan semua folder AlbumName dengan struktur dan konten yang sesuai ...".
tidak ada yang
2
Oh begitu. Saya tidak yakin. Apakah hanya file flac yang perlu disalin atau seluruh folder yang memiliki setidaknya satu file flac?
tidak ada yang
Pertanyaannya diedit dan sekarang menjelaskan lebih detail, apa yang diinginkan fricadelle. Dipertimbangkan bahwa semua konten akan disalin, jika ada file flac, jawaban saya salah karena hanya menyalin file flac. Namun mungkin masih bermanfaat untuk tujuan lain.
tidak ada yang
9

hai temanku bisa kamu gunakan

mkdir newdirectory
cp -r --parents */*.flac newdirectory/
amir.m ghazanfari
sumber
2
Bagus tidak pernah digunakan --parentssebelumnya!
George Udosen
4
Tolong jelaskan ini */*.flac! Tidak akan cp -r --parents AlbumName/ newdirectory/cukup?
George Udosen
3
Dari pertanyaan, sepertinya flac mungkin ada atau tidak ada di direktori bersarang, jadi saya sarankan untuk mengaktifkan globstar ( shopt -s globstar), lalu gunakan **/*.flacuntuk glob. Bintang ganda akan cocok dengan nol atau lebih direktori.
wjandrea
Anda wjandrea benar, biarkan saya mengedit pertanyaan saya sehingga semua orang mengerti
fricadelle
5

Jawaban yang bagus

Saya ingin menambahkan satu cara lagi, Anda juga dapat menggunakan kombinasi find dan cpio

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

Penjelasan:

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.

Ada 3 mode cpio:

  • Mode salin: 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 salin: 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 salin-pas: 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.

Di sini, kami menggunakan mode Copy-pass.

  • Opsi yang digunakan dalam perintah di atas:

Temukan:

  • -name -> nama file atau gunakan regex alih-alih menulis nama lengkap

cpio:

  • '-m, --preserve-modifikasi-waktu' Retain previous file modification times when creating files.
  • '-p, - lewati' Run in copy-pass mode. see ``Copy-pass mode``.
  • '-d, --membuat-direktori' Create leading directories where needed.'
  • --quiet' Jangan cetak jumlah blok yang disalin.`

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.

Satu juga dapat menggunakan rsyncatau menulis skrip shell untuk menemukan dan menyalin file dengan struktur direktori.

Untuk penjelasan Rsync, Silakan lihat jawaban di atas.

bsdboy
sumber
2
Anda dapat meningkatkan jawaban Anda dengan memasukkan penjelasan perintah dan opsi yang Anda sarankan. - Dari Ulasan
J. Starnes
@D yeah, benar. Terima kasih, atas saran sempurna Anda.
bsdboy
4

Jawaban 1: Anda juga dapat menggunakan findperintah yang sama.

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

Penjelasan:

mkdirmembuat direktori baru. findperintah ditemukan*.flac file yang terletak di AlbumNamefolder. execperintah mengeksekusi cpperintah untuk masing-masing nama file yang findtelah kembali.

Jawaban 2: Anda juga dapat menggunakan findperintah dengan xargsserta

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

Informasi lebih lanjut: temukan , xargs

mf_starboi_8041
sumber
1
find | xargsakan merusak nama file dengan spasi, alih- find -print0 | xargs -0alih gunakan .
hidangan penutup
Saya mencoba dengan 1 2.flacfile yang memiliki ruang dalam nama file. Bisakah Anda memberi tahu saya nama file yang find | xargsgagal?
mf_starboi_8041
lihat misalnya di sini
makanan penutup
Saya tidak tahu, tetapi saya dapat menyalin file dengan nama panjang yang memiliki ruang di dalamnya tanpa menggunakanfind -print0 | xargs -0
mf_starboi_8041
Coba touch "a space" && find . | xargs ls.
hidangan penutup
0

Baru saja menyelesaikan masalah yang sama untuk perpustakaan musik saya dan menyelesaikannya menggunakan skrip yang disesuaikan berikut ini. Saya tidak sepenuhnya merekayasa dengan variabel yaitu, karena saya hanya bermaksud menggunakannya sekali :).

Script memindahkan setiap direktori yang berisi file flac termasuk semua file lain dan subdirektori ke lokasi baru menggunakan rsync. rsync memungkinkan Anda untuk melanjutkan skrip jika berhenti selama proses.

Struktur perpustakaan saya:

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

Struktur perpustakaan baru:

library
|-artist
  |- album 1 (mp3)

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

(1) mulai skrip shell berikut di tujuan SUMBER (ganti TARGET dengan direktori masing-masing pilihan Anda - Saya baru saja menggunakan jalur absolut)

baris 1: temukan semua direktori yang berisi file flac dan pipa (|) yang menjadi sortir
baris 2: hapus duplikat dengan sortir dan pipa yang daftar ke dalam do loop
baris 3: untuk setiap direktori lakukan
baris 4: tunjukkan direktori dalam proses
baris 5: rsync ke direktori target plus hapus sumber dan struktur pertahankan (-R) di
baris lokasi target 6: hapus direktori kosong (karena rsync hanya menghapus file)

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) setelah berhasil mengeksekusi skrip di (1) Anda dapat menjalankan perintah berikut di direktori sumber

find . -depth -type d -empty -delete

Perintah ini menghapus semua direktori kosong yang tidak dihapus dalam skrip. Yakni direktori "Artis", di mana semua subfolder / album menyertakan file flac.

wundabua
sumber