ทำการซิปไฟล์ซ้ำเป็น. cbz-files โดยอ้างอิงจากโฟลเดอร์ในบรรทัดคำสั่ง


2

ฉันพยายามหาวิธีเขียนสคริปต์เพื่อสร้างไฟล์. cbz จากรูปภาพในโฟลเดอร์ใน OSX โดยอัตโนมัติ

แผนผังไดเรกทอรีของฉันจะมีลักษณะเช่นนี้:

/toplevel/
cbz/
comics/
    Comic1/
        comic1file1.jpg
        comic1file2.gif
        comic1file3.png
    Comic2/
        comic2file1.jpg
        comic2file2.gif
    Publisher/
            Comic3/
                comic3file1.jpg
                comic3file2.gif
                comic3file3.png
            Comic4/
                comic4file1.jpg
                comic4file2.gif

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

ตำแหน่งที่ฉันอยู่: ตัวอย่างนี้จะมองผ่านโฟลเดอร์และสร้างไฟล์. cbz สำหรับแต่ละโฟลเดอร์ย่อย

for dir in `ls`; do zip $dir $dir/*; mv $dir*zip $dir.cbz; done

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


ยินดีต้อนรับสู่ SU! เราไม่ใช่บริการเขียนสคริปต์ คุณได้อะไรมาไกลขนาดนี้? คุณติดอยู่ที่ไหน
Ƭᴇcʜιᴇ007

ฉันขอโทษถ้านั่นเป็นวิธีที่ฉันเจอ ฉันได้รวบรวมตัวอย่างนี้ที่จะทำงานสำหรับโฟลเดอร์ระดับเดียว: ´สำหรับ dir ls; ทำ zip $ dir $ dir / *; mv $ dir * zip $ dir.cbz; เสร็จแล้วและฉันพยายามทำให้มันมองหาโฟลเดอร์ย่อย อุปสรรค์ที่ใหญ่ที่สุดของฉันตอนนี้กำลังพิจารณาว่าโฟลเดอร์มีโฟลเดอร์ย่อยหรือไฟล์อยู่หรือไม่
Martin

ไม่ต้องห่วง. โปรดแก้ไขคำถามของคุณและรวมถึงสิ่งที่คุณได้รับมาแล้วและอธิบายว่าคุณกำลังติดขัดในการแก้ไขเพื่อทำสิ่งที่คุณต้องการได้อย่างไร
Ƭᴇcʜιᴇ007

คำตอบ:


4

อีกโซลูชันที่แตกต่างกันเล็กน้อย:

#!/bin/bash
find toplevel/comics -type d -not -empty -print0 | while IFS= read -r -d '' dir; do
  if find "$dir" -maxdepth 1 -type f | read f; then
    zip toplevel/cbz/"$(basename "$dir").cbz" "$dir"/*
  fi
done
  • find … -print0 | while IFS= read -r -d '' fileเป็นรูปแบบที่แนะนำให้ทำซ้ำมากกว่าfindผลลัพธ์ การดำเนินการอย่างง่าย ๆ นั้นfind … | while read fileใช้ได้ผลดี แต่ถ้าชื่อไฟล์ที่ส่งคืนไม่มีการขึ้นบรรทัดใหม่ lsไม่แนะนำให้ทำการแยกวิเคราะห์

  • find "$dir" -maxdepth 1 -type f | read fประเมินค่าจริงถ้าพบไฟล์ในไดเรกทอรี มันประสบความสำเร็จวัตถุประสงค์เดียวกันของการประเมินผลของ @ terdon findจำนวนของการส่งออกเส้นโดย

  • จำเป็นต้องใช้เครื่องหมายคำพูดล้อมรอบตัวแปรทั้งหมดเพื่อป้องกันช่องว่างในชื่อไฟล์ไม่ให้เกิดการขัดแย้ง


ดีฉลาดที่จะใช้readวิธีการนั้น
terdon

ดูเหมือนว่าจะทำงานได้อย่างสวยงาม! ฉันจะยอมรับคำตอบทันทีที่สคริปต์เสร็จสิ้นและฉันสามารถตรวจสอบหนึ่งในจดหมายเหตุ :)
Martin

2

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

find toplevel/comics/ -mindepth 1 -type d | 
while read dir; do 
    num=$(find "$dir" -mindepth 1 -maxdepth 1 -type f | wc -l )  
    [ "$num" -gt "0" ] && zip toplevel/cbz/"$(basename $dir)".cbd "$dir"/*; 
done

findคำสั่งที่1 ค้นหาtoplevel/comics/ไดเรกทอรี ( type -d) ที่มีอย่างน้อยหนึ่งระดับด้านล่าง ( -mindepth 1) เส้นทางที่กำหนด (ไดเรกทอรีย่อย) สิ่งนี้ทำให้มั่นใจได้ว่าfindจะไม่ส่งคืนผลที่toplevel/comicsตามมา ผลการพบว่ามีการประปาไปยังห่วงซึ่งกระบวนการแต่ละของพวกเขาบันทึกไว้ในตัวแปรwhile $dirแต่ละ$dirไฟล์จะค้นหาไฟล์ ( -type f) ที่อยู่ในไดเรกทอรีนั้นจริงและไม่อยู่ในไดเรกทอรีย่อย ( -mindepth 1 -maxdepth 1) จำนวนของสายกลับโดยที่find(ว่าเป็นสิ่งที่wcไม่) จะถูกบันทึกเป็น$numและถ้ามันเป็นมากกว่า 0 cbzไดเรกทอรีซิปและข้อมูลที่เก็บอยู่ใน

หมายเหตุ: ไฟล์เก็บถาวรจะมีเส้นทางแบบเต็มไปยังไฟล์ (ทดสอบโดยการเปิดออกหนึ่งไฟล์) คุณอาจต้องการให้-jตัวเลือกzipหากคุณไม่ต้องการสิ่งนี้ man zipดู


1
เอาชนะฉันให้ได้ คุณอาจต้องการอ้างอิงสองครั้งtoplevel/cbz/$(basename "$dir").cbdในกรณีที่ชื่อฐานขยายด้วยช่องว่าง find … -print0 | while IFS= read -r -d '' dir; do …สำหรับการจัดการไฟล์หวาดระแวงจริงๆมันควรจะเป็น
slhck

@slhck จุดที่ดีเกี่ยวกับ$(basename "$dir")คำตอบแก้ไข ฉันไม่ได้รวม IFS และอื่น ๆ เพื่อให้สิ่งต่าง ๆ เรียบง่ายเนื่องจาก OP เพิ่งเริ่มต้นด้วยเชลล์สคริปต์และเนื่องจากคุณมีมันในเวอร์ชันของคุณ
terdon

สิ่งนี้ดูมีแนวโน้มมาก แต่ก็มีบางอย่างที่ขัดขวาง ทำการปรับเปลี่ยนบางอย่างเพื่อสะท้อนโครงสร้างไฟล์จริงที่ฉันลงเอยด้วยการบันทึกเป็น "cbzmaker.sh" ในสิ่งที่จะเป็น "toplevel" dir: #! /bin/bash find Comics -mindepth 1 -type d | while read dir; do num=$(find "$dir" -mindepth 1 -maxdepth 1 -type f | wc -l ) [ "$num" -gt "0" ] && zip CBZs/"$(basename $dir)".cbz "$dir"; done ดูเหมือนว่าจะค้นหาโฟลเดอร์ทั้งหมดและสร้างรหัสไปรษณีย์ตามชื่อของพวกเขา แต่พวกเขาทั้งหมดดูเหมือนจะ ว่างเปล่า
Martin

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