Belirli bir dosya içeren tüm klasörleri kopyalama


17

Yalnızca FLAC müzik klasörlerimi yedeklemek istiyorum. FLAC dosyaları klasörlerin içine yerleştirilebilir:

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

Tüm AlbumName'in klasörlerini, en az bir FLAC dosyasının içinde bir yerde bulunan ilgili yapı ve içeriklerle nasıl kopyalayıp taşıyabilirim (bunu söylemek için yeterli olduğunu varsayacağım: müzik FLAC formatında)

EDIT: FLAC dosyaları iç içe olabilir ; böylece olabilir:

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

Ve bu klasörleri sadece FLAC dosyaları ile değil, tüm içeriği ile kopyalamak ve başka bir dizine yapıştırmak istiyorum.

Yani benim de

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

ve

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

Başka bir dizine özyinelemeli olarak AlbumName, AlbumName2 ve AlbumName3 istiyorum ama AlbumName4 değil

EDIT: Cevapların hiçbiri gerçekten istediğimi yapmıyordu, bu yüzden böyle bir şey kullandım:

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

temelde tüm flac dosyalarını listeliyorum, awk kullanarak kök klasörü alıyorum, kopyaları siliyorum ve istediğimi yapıyorum


nereye yedekleme, hedefiniz nedir?
George Udosen

Yalnızca flac dosyalarının veya en az bir flac dosyası olan tüm klasörlerin kopyalanması gerekir mi?
kimse

@nobody folders: " Tüm AlbumName klasörlerini, en az bir FLAC dosyasının içinde bir yerde bulunan ilgili yapı ve içeriklerle nasıl kopyalayıp taşıyabilirim "
terdon

Yanıtlar:


19

Bir seçenek, yalnızca flac dosyalarını kopyalayan ve dizin yapısını koruyan rsync kullanmaktır:

rsync -avzm --include=*/ --include=*.flac --exclude=* albums/ backup/
  • bir arşiv
  • v ayrıntılı
  • z aktarım sırasında sıkıştır (aynı bilgisayarda kopyalamak yararlı olmayabilir)
  • boş kirleri erik
  • önce tüm dizinleri içerir
  • İkincisi flac dosyalarını içerir
  • son hariç tutma diğer tüm dosyaları hariç tutar

Gerçekten mi? Anlıyorum, dizin yapısını korumak istiyor. Diyor ki: "Tüm AlbumName klasörlerini ilgili yapıları ve içerikleriyle nasıl kopyalarım ve taşırım ...".
kimse

2
Ah anlıyorum. Emin değilim. Yalnızca flac dosyalarının veya en az bir flac dosyası olan tüm klasörlerin kopyalanması gerekir mi?
kimse

Soru düzenlenmiştir ve şimdi daha fazla, fricadelle'nin ne istediğini açıklamaktadır. Tüm içeriğin kopyalanacağı dikkate alınırsa, bir flac dosyası varsa, cevabım sadece flac dosyalarını kopyaladığından yanlıştır. Ancak yine de başka bir amaç için yararlı olabilir.
kimse

9

merhaba arkadaşım kullanabilirsin

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

2
Daha --parentsönce hiç kullanılmamış güzel !
George Udosen

4
Lütfen bunu açıklayın */*.flac! Will cp -r --parents AlbumName/ newdirectory/yeterli değil?
George Udosen

3
Sorudan, kulağa iç içe dizinlerde olabilir veya olmayabilir gibi geliyor, bu yüzden globstar'ı ( shopt -s globstar) etkinleştirmenizi ve ardından **/*.flacglob için kullanmanızı tavsiye ederim . Çift yıldız sıfır veya daha fazla dizinle eşleşir.
wjandrea

tam olarak haklısın wjandrea, herkesin anlaması için
sorumu

5

Güzel cevaplar

Bir yol daha eklemek istiyorum, ayrıca find ve cpio kombinasyonunu da kullanabilirsiniz

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

Açıklama:

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.

3 cpio modu vardır:

  • Kopyalama modu: 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.

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

  • Kopyalama modu: 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.

Burada, Kopyala geçiş modunu kullanıyoruz.

  • Yukarıdaki komutta kullanılan seçenekler:

bulmak:

  • -name -> dosya adı veya tam ad yazmak yerine normal ifade kullan

cpio:

  • '-m, --preserve-modifikasyon-zaman' Retain previous file modification times when creating files.
  • '-P - geçiş' Run in copy-pass mode. see ``Copy-pass mode``.
  • '-d, --make-dizinleri' Create leading directories where needed.'
  • --quiet' Kopyalanan blok sayısını yazdırmayın. '

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.

Ayrıca rsyncdizin yapısı ile dosyaları bulmak ve kopyalamak için bir kabuk komut dosyası kullanabilir veya yazabilirsiniz.

Rsync açıklaması için lütfen yukarıdaki cevaplara bakınız.


2
Komutların açıklamalarını ve önerdiğiniz seçenekleri ekleyerek yanıtınızı geliştirebilirsiniz. - Yorumdan
J. Starnes

@ tatlı evet, doğru. Mükemmel öneriniz için teşekkür ederim.
bsdboy

4

Cevap 1:find Aynı komutu da kullanabilirsiniz .

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

Açıklama:

mkdiryeni dizin oluşturur. findkomutu klasörde *.flacbulunan dosyaları bulur AlbumName. execcommand , döndürülen cpher dosya adına komut yürütür find.

2 Cevap: da kullanabilirsiniz findile komutu xargsyanı

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

Daha fazla bilgi: bul , xargs


1
find | xargsboşluklu dosya adlarını kıracak, find -print0 | xargs -0onun yerine kullanacak .
tatlı

ben 1 2.flacdosya adında boşluk olan dosya ile çalıştı . find | xargsBaşarısız olan dosya adını bana bildirir misiniz?
mf_starboi_8041

örneğin burada
tatlı

Bilmiyorum ama kullanmadan içinde yer alan uzun isim ile dosya kopyalamak mümkünfind -print0 | xargs -0
mf_starboi_8041 21:17

Deneyin touch "a space" && find . | xargs ls.
tatlı

0

Sadece benim müzik kütüphanem için aynı sorunu çözmek ve aşağıdaki uyarlanmış komut dosyası kullanarak çözdü. Ben sadece bir kez kullanmak niyetinde olduğu gibi, yani değişkenler ile tamamen mühendislik yoktu :).

Komut dosyası, diğer tüm dosyalar ve alt dizinler dahil flac dosyalarını içeren her dizini rsync kullanarak yeni bir konuma taşır. rsync, işlem sırasında durursa komut dosyasını sürdürmenizi sağlar.

Kütüphane yapım:

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

Yeni kütüphane yapısı:

library
|-artist
  |- album 1 (mp3)

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

(1) SOURCE hedefinde aşağıdaki kabuk betiğini başlatın (TARGET'i seçtiğiniz ilgili dizine değiştirin - sadece mutlak yolu kullandım)

satır 1:
sıra 2'ye flac dosyaları ve pipe (|) içeren tüm dizinleri bulun satır 2: sıraları ve do ile listeleyen pipetlerini do döngü
satırına 3 kaldırın : her dizin için
satır 4: dizini işlem
satırı 5'te gösterin : hedef dizine rsync artı hedef konumu
satır 6'daki kaynağı kaldır ve yapıyı (-R) koru : boş dizini kaldır (rsync yalnızca dosyaları kaldırdığı için)

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) (1) 'de komut dosyasını başarıyla yürüttükten sonra, kaynak dizinde aşağıdaki komutu yürütebilirsiniz

find . -depth -type d -empty -delete

Bu komut komut dosyasında silinmeyen tüm boş dizinleri siler . Yani tüm sanatçıların / albümlerin flac dosyaları içerdiği "Artist" dizinleri.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.