วิธีคัดลอกโฟลเดอร์ทั้งหมดที่มีไฟล์เฉพาะ


17

ฉันต้องการสำรองเฉพาะโฟลเดอร์เพลง FLAC ของฉัน ไฟล์ FLAC สามารถซ้อนกันเช่นนั้นภายในโฟลเดอร์:

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

ฉันจะคัดลอกและย้ายโฟลเดอร์ของ AlbumName ทั้งหมดด้วยโครงสร้างและเนื้อหาที่เกี่ยวข้องที่มีที่อยู่ภายในไฟล์ FLAC อย่างน้อยหนึ่งไฟล์ (ฉันจะถือว่านี่เพียงพอที่จะพูดได้ว่า: เพลงอยู่ในรูปแบบ FLAC)

แก้ไข: ไฟล์ FLAC สามารถซ้อนกัน; ดังนั้นฉันสามารถมี:

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

และฉันต้องการคัดลอกโฟลเดอร์เหล่านั้นด้วยเนื้อหาทั้งหมดไม่เพียง แต่ไฟล์ FLAC และวางไปยังไดเรกทอรีอื่น

ดังนั้นถ้าฉันมีเช่นกัน

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

และ

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

ฉันต้องการ cp ซ้ำไปยังไดเรกทอรีอื่น AlbumName, AlbumName2 และ AlbumName3 แต่ไม่ใช่ AlbumName4

แก้ไข: ไม่มีคำตอบใดที่ทำสิ่งที่ฉันต้องการจริงๆดังนั้นฉันจึงใช้สิ่งนี้:

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

โดยทั่วไปฉันรายการไฟล์ flac ทั้งหมดฉันดึงโฟลเดอร์รูทโดยใช้ awk ฉันลบไฟล์ที่ซ้ำกันและฉันทำสิ่งที่ฉันต้องการ


สำรองข้อมูลไปยังที่ปลายทางของคุณคืออะไร
George Udosen

จำเป็นต้องคัดลอกไฟล์ flac หรือทั้งโฟลเดอร์ที่มีไฟล์ flac อย่างน้อยหนึ่งไฟล์หรือไม่
ไม่มีใคร

@nobody โฟลเดอร์: " ฉันจะคัดลอกและย้ายโฟลเดอร์ AlbumName ทั้งหมดได้อย่างไรด้วยโครงสร้างและเนื้อหาที่เกี่ยวข้องที่มีที่อยู่ภายในไฟล์ FLAC อย่างน้อยหนึ่งไฟล์ "
terdon

คำตอบ:


19

ตัวเลือกคือการใช้ rsync ซึ่งคัดลอกเฉพาะไฟล์ flac และรักษาโครงสร้างไดเรกทอรี:

rsync -avzm --include=*/ --include=*.flac --exclude=* albums/ backup/
  • เก็บถาวร
  • v verbose
  • บีบอัด z ระหว่างการถ่ายโอน (อาจไม่มีประโยชน์ในการคัดลอกในคอมพิวเตอร์เครื่องเดียวกัน)
  • m ตัดลูกพรุนที่ว่างเปล่า
  • แรก ได้แก่ รวมถึงไดเรกทอรีทั้งหมด
  • ที่สองรวมถึงไฟล์ flac
  • การยกเว้นครั้งสุดท้ายจะแยกไฟล์อื่น ๆ ทั้งหมด

จริงๆ? ฉันเข้าใจว่าเขาต้องการรักษาโครงสร้างไดเรกทอรี เขากล่าวว่า: "ฉันจะคัดลอกและย้ายโฟลเดอร์ของ AlbumName ทั้งหมดได้อย่างไรด้วยโครงสร้างและเนื้อหาที่เกี่ยวข้อง ... "
ไม่มีใคร

2
อ้อเข้าใจแล้ว. ฉันไม่แน่ใจ. จำเป็นต้องคัดลอกไฟล์ flac หรือทั้งโฟลเดอร์ที่มีไฟล์ flac อย่างน้อยหนึ่งไฟล์หรือไม่
ไม่มีใคร

คำถามนี้ได้รับการแก้ไขแล้วและในตอนนี้จะอธิบายรายละเอียดเพิ่มเติมสิ่งที่เฟรเดลต้องการ คำนึงถึงว่าเนื้อหาทั้งหมดจะถูกคัดลอกหากมีไฟล์ flac คำตอบของฉันไม่ถูกต้องเพราะมันคัดลอกไฟล์ flac เท่านั้น อย่างไรก็ตามมันอาจยังมีประโยชน์สำหรับวัตถุประสงค์อื่น
ไม่มีใคร

9

สวัสดีเพื่อนของฉันคุณสามารถใช้

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

2
นิสัยดีไม่เคยใช้มา--parentsก่อน!
George Udosen

4
กรุณาอธิบายสิ่งนี้*/*.flac! จะcp -r --parents AlbumName/ newdirectory/ไม่พอเพียง?
George Udosen

3
จากคำถามดูเหมือนว่า flacs อาจหรืออาจจะไม่อยู่ในไดเรกทอรีที่ซ้อนกันดังนั้นฉันขอแนะนำให้เปิดใช้งาน globstar ( shopt -s globstar) จากนั้นใช้**/*.flacสำหรับ glob ดาวคู่จะตรงกับศูนย์หรือมากกว่าไดเรกทอรี
wjandrea

คุณพูดถูกต้องแล้วขอให้ฉันแก้ไขคำถามของฉันเพื่อให้ทุกคนเข้าใจ
fricadelle

5

คำตอบที่ดี

ฉันต้องการเพิ่มอีกวิธีคุณสามารถใช้การรวมกันของfindและcpio

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

คำอธิบาย:

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:

  • โหมดคัดลอกออก: 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.

  • โหมดคัดลอก: In copy-in mode, cpio copies files out of an archive or lists the archive contents. It reads the archive from the standard input.

  • โหมดถ่ายสำเนา: 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.

ที่นี่เราใช้โหมดคัดลอกพาส

  • ตัวเลือกที่ใช้ในคำสั่งด้านบน:

หา:

  • -name -> ชื่อไฟล์หรือใช้ regex แทนการเขียนชื่อเต็ม

cpio:

  • '-m, - ป้องกันการแก้ไขเวลา' Retain previous file modification times when creating files.
  • '-p, - ส่งผ่าน' Run in copy-pass mode. see ``Copy-pass mode``.
  • '-d, - ทำให้ไดเรกทอรี' Create leading directories where needed.'
  • --quiet' อย่าพิมพ์จำนวนบล็อกที่คัดลอก '

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.

ท่านสามารถใช้rsyncหรือเขียนเชลล์สคริปต์เพื่อค้นหาและคัดลอกไฟล์ด้วยโครงสร้างไดเรกทอรี

สำหรับคำอธิบาย Rsync โปรดดูคำตอบข้างต้น


2
คุณสามารถปรับปรุงคำตอบของคุณโดยรวมถึงคำอธิบายของคำสั่งและตัวเลือกที่คุณแนะนำ - จากการรีวิว
J. Starnes

@dessert ใช่แล้ว ขอบคุณสำหรับคำแนะนำที่สมบูรณ์แบบของคุณ
bsdboy

4

คำตอบ 1:คุณสามารถใช้findคำสั่งเหมือนกันได้

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

ชี้แจง:

mkdirสร้างไดเรกทอรีใหม่ findคำสั่งค้นหา*.flacไฟล์ที่อยู่ในAlbumNameโฟลเดอร์ execคำสั่งดำเนินการcpคำสั่งไปยังแต่ละชื่อไฟล์ที่findได้กลับมา

คำตอบ 2:คุณสามารถใช้findคำสั่งด้วยxargsเช่นกัน

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

ข้อมูลเพิ่มเติม: ค้นหา , xargs


1
find | xargsจะแตกชื่อไฟล์ด้วยช่องว่างแทนที่จะใช้find -print0 | xargs -0แทน
ของหวาน

ฉันลองกับ1 2.flacไฟล์ที่มีช่องว่างในชื่อไฟล์ คุณช่วยบอกให้ฉันรู้ชื่อไฟล์ที่find | xargsล้มเหลวได้ไหม?
mf_starboi_8041

ดูตัวอย่างได้ที่นี่
ของหวาน

ฉันไม่รู้ แต่ฉันสามารถคัดลอกไฟล์ที่มีชื่อยาวซึ่งมีพื้นที่ในไฟล์โดยไม่ใช้find -print0 | xargs -0
mf_starboi_8041

ลองtouch "a space" && find . | xargs lsดู
ของหวาน

0

เพิ่งมีการแก้ไขปัญหาเดียวกันสำหรับคลังเพลงของฉันและแก้ไขโดยใช้สคริปต์ที่ปรับเปลี่ยนต่อไปนี้ ฉันไม่ได้สร้างมันอย่างเต็มที่ด้วยตัวแปรเช่นฉันตั้งใจจะใช้เพียงครั้งเดียว :)

สคริปต์ย้ายทุกไดเร็กทอรีที่มีไฟล์ flac รวมถึงไฟล์และไดเร็กทอรีย่อยอื่นทั้งหมดไปยังตำแหน่งใหม่โดยใช้ rsync rsync ช่วยให้คุณสามารถเรียกใช้สคริปต์ต่อถ้าหยุดในระหว่างกระบวนการ

โครงสร้างห้องสมุดของฉัน:

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

โครงสร้างห้องสมุดใหม่:

library
|-artist
  |- album 1 (mp3)

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

(1) เริ่มเชลล์สคริปต์ต่อไปนี้ในปลายทาง SOURCE (แทนที่เป้าหมายด้วยไดเรกทอรีตามลำดับที่คุณเลือก - ฉันเพิ่งใช้พา ธ สัมบูรณ์)

แถว 1: ค้นหาไดเรกทอรีทั้งหมดที่มีไฟล์ flac และไปป์ (|) ที่อยู่ใน
แถวเรียงลำดับที่2: ลบรายการที่ซ้ำกันด้วยการเรียงลำดับและไปป์ที่รายการลงใน
แถววนรอบ Do 3: สำหรับแต่ละไดเรกทอรีทำ
แถว 4: แสดงไดเรกทอรีในกระบวนการ
แถว 5: rsync ไปยังไดเรกทอรีเป้าหมายพร้อมลบแหล่งข้อมูลและเก็บรักษาโครงสร้าง (-R) ใน
แถวตำแหน่งเป้าหมาย6: ลบไดเรกทอรีว่างเปล่า (เนื่องจาก rsync ลบเฉพาะไฟล์)

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) สำเร็จคุณสามารถใช้คำสั่งต่อไปนี้ในไดเรกทอรีต้นทาง

find . -depth -type d -empty -delete

คำสั่งนี้จะลบไดเรกทอรีว่างเปล่าทั้งหมดที่ไม่ได้ลบภายในสคริปต์ นั่นคือไดเรกทอรี "ศิลปิน" ซึ่งโฟลเดอร์ย่อย / อัลบั้มทั้งหมดรวมไฟล์ flac

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.