ไฟล์ tar เท่านั้นไม่มีไดเร็กทอรี


16

ฉันอาจจะเขียนเชลล์สคริปต์เพื่อค้นหาไฟล์เท่านั้นจากนั้นส่งรายการไปยัง tar แต่ฉันสงสัยว่ามีคุณลักษณะในตัวใน tar ที่อนุญาตให้ทำเช่นนั้นในบรรทัดคำสั่งเดียวหรือไม่

ตัวอย่างเช่นฉันพบ--no-recursionสวิตช์ แต่เมื่อฉัน:

tar --no-recursion -cvf mydir.tar mydir

มันเก็บเฉพาะชื่อของรายการในไดเรกทอรี (รวมถึงไดเรกทอรีย่อย!) แต่มันไม่ได้เก็บไฟล์ใด ๆ

ฉันก็ลอง:

 tar --no-recursion -cvf mydir.tar mydir/*

แต่ในขณะที่มันเก็บไฟล์เท่านั้นมันยังเก็บชื่อของไดเรกทอรีย่อย

มีวิธีบอกไฟล์ tar เท่านั้นไม่มีไดเรกทอรีหรือไม่


5
เพื่อชี้แจง: คุณต้องการสร้างไฟล์เก็บถาวรที่มีโครงสร้าง "แบน" (เช่นไฟล์ทั้งหมดรวมกันในไดเรกทอรีเดียว) หรือไม่
rozcietrzewiacz

1
คุณสามารถสร้างไดเรกทอรีใหม่find mydir -type f |xargs cp -t tempdirและจากนั้น tar tempdir
Kevin

@rozcietrzewiacz ใช่แบน แต่เฉพาะจากไดเรกทอรีนั้นไม่ใช่จากไดเรกทอรีย่อย
ateiob

1
ตกลงฉันคิดว่าฉันเห็นสิ่งที่คุณกำลังพยายามทำ แล้วfind mydir -depth 1 -type f | xargs tar cf mydir.tar
เควิน

2
อาช่องว่าง ใช้การค้นหาเป็น -exec find mydir -maxdepth 1 -type f -exec tar cvf mydir.tar {} +แทน: +ทำให้ทุกไฟล์บนบรรทัดคำสั่งเช่นเดียวกับ xargs
เควิน

คำตอบ:


11

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

find mydir -maxdepth 1 -type f -print0 | xargs -0 tar Avf mydir.tar
find mydir -maxdepth 1 -type f -exec tar Avf mydir.tar {} +

คำตอบ Iocnarz ของการใช้tar's --nullและ-Tตัวเลือกการทำงานได้เป็นอย่างดี หากคุณcpioติดตั้งแล้วคำตอบของ camh ที่ใช้ก็ใช้ได้เช่นกัน และถ้าคุณมีzshและไม่รังเกียจที่จะใช้มันสำหรับคำสั่งคำตอบของ Gilles โดยใช้ zsh glob ( *(.)) ดูเหมือนจะตรงไปตรงมาที่สุด


กุญแจสำคัญคือ-maxdepthตัวเลือก คำตอบสุดท้ายจัดการกับช่องว่างอย่างเหมาะสม:

find mydir -maxdepth 1 -type f -print0 | xargs -0 tar cvf mydir.tar

สิ่งนี้ควรใช้:

find mydir -maxdepth 1 -type f -exec tar cvf mydir.tar {} +

4
tarทั้งสองคนนี้จะส่งผลให้ในหลายสวดของ ทั้งสองxargsและfindกับ+ตัวแปรที่มีจำนวนสูงสุดของการขัดแย้งที่สามารถส่งผ่านไปยัง tar ซึ่งจะส่งผลให้การร้องขอที่สองของ tar เขียนทับเอาต์พุตของครั้งแรก
camh

2
การขยายขีด จำกัด xargs, xargs เริ่มต้นเป็นบรรทัดคำสั่ง 128KiB สูงสุด หากรายการไฟล์มีขนาดใหญ่ขึ้นคุณจะได้รับการร้องขอคำสั่ง (tar) ครั้งที่สอง (หรือมากกว่า) ซึ่งนำไปสู่การสูญเสียข้อมูลที่เงียบ คุณสามารถใช้-xบังคับให้ xargs ล้มเหลวแทนการสูญเสียข้อมูลและในขณะที่ดีกว่าข้อผิดพลาดการสูญเสียข้อมูลแบบเงียบ แต่ก็ยังไม่เหมาะ ข้อผิดพลาดการเรียงลำดับนี้อันตรายมากเพราะทุกอย่างดูโอเคในตอนแรก แต่เมื่อรายชื่อไฟล์ขยายตัวเมื่อเวลาผ่านไปคุณจะเริ่มทำงานและอาจไม่สังเกตจนกว่าคุณจะพยายามกู้คืนข้อมูลสำรองของคุณ ถ้าอย่างนั้นมันก็สายเกินไป
camh

@camh ถูกต้องขอบคุณที่ชี้ให้เห็น; ฉันได้รับการปรับปรุงเพื่อสะท้อนให้เห็นว่า
เควิน

1
"คำตอบสุดท้าย" ไม่ถูกต้องหากคุณใช้ "tar c" โดยไม่มี -T คุณอาจได้รับผลลัพธ์บางส่วน
eckes

14

เมื่อคุณต้องการที่จะใช้findกับtarวิธีที่ดีที่สุดคือการใช้แทนcpio สามารถเขียน tar เก็บถาวรและถูกออกแบบมาเพื่อใช้รายการไฟล์ที่จะเก็บถาวรจาก stdintarcpio

find mydir -maxdepth 1 -type f -print0 | cpio -o -H ustar -0 > mydir.tar

การใช้findและcpioเป็นวิธีที่ใช้ unix-y มากขึ้นในการที่คุณอนุญาตให้findทำการเลือกไฟล์ด้วยพลังงานทั้งหมดที่มีอยู่และcpioการจัดเก็บลงสื่อถาวร มันเป็นมูลค่าการเรียนรู้นี้ใช้งานง่ายของการเป็นคุณพบว่ามันง่ายต่อการแก้ปัญหาของคุณปังข้างหน้าของคุณกับเมื่อพยายามcpiotar


ยอดเยี่ยม! ฉันเคยใช้ cpio ในอดีตอันไกลโพ้น แต่ไม่เคยรู้เลยว่ามีตัวเลือกยูสตาร์หรือไม่
Ian McGowan

2
มันทำงานได้ดีกว่าสำหรับฉันมากกว่าคำตอบที่ยอมรับ
เดลเดอร์สัน

1
แค่นิดหน่อย -maxdepth 1 ควรมาก่อน -type f หรือคุณจะได้รับคำเตือนจากการค้นพบบางอย่าง
kdubs

ขอบคุณ @kdubs ฉันได้อัปเดตคำตอบ-maxdepthก่อนหน้า-typeนี้แล้ว
camh

3

ฉันไม่แน่ใจว่าฉันเข้าใจความต้องการของคุณ หากคุณต้องการจัดเก็บไฟล์ปกติในmydirแต่ไม่ใช่ไดเรกทอรีย่อยวิธีที่ง่ายที่สุดคือการใช้ zsh โดยที่การจับคู่ไฟล์ปกติเท่านั้นเป็นเรื่องง่าย ๆ ในการใช้ตัวระบุ. glob :

tar cf mydir.tar mydir/*(.)

3

คุณสามารถใช้find ... -print0และtar ... --nullโดยตรงได้โดยไม่ต้องใช้xargsเลย

find . -maxdepth 1 -type f -print0 | tar cvf mydir.tar --null -T -

ในตัวอย่างที่ได้รับการ--no-recursionเลือกที่จะtarไม่จำเป็นเพราะเพียงเส้นทางของไฟล์ (และไม่ไดเรกทอรี) จะถูกส่งผ่านจากไปfindtar

อย่างไรก็ตามการใช้--no-recursionตัวเลือกtarในตัวอย่างต่อไปนี้ป้องกันไม่ให้tarไดเรกทอรีเก็บถาวรสองครั้ง findจะทำ recursion ต้นไม้ไดเรกทอรีแทนtarแล้ว

# compare
find . -print0 | tar cf mydir.tar --null -T -
tar -tf mydir.tar | nl

find . -print0 | tar cf mydir.tar --null --no-recursion -T -
tar -tf mydir.tar | nl

2

ตามวรรคเกริ่นนำในman tarพูดว่า (ประโยคสุดท้าย)

การใช้ชื่อไดเรกทอรีจะบอกเป็นนัยว่าไดเรกทอรีย่อยด้านล่างควรรวมอยู่ในไฟล์เก็บถาวร

ซึ่งฉันเข้าใจว่าเป็นคำตอบ "ไม่" สำหรับคำถามของคุณ


ดีจับยกเว้น tar ว่าในขณะนี้มีการยกเว้น meachisms จำนวนมาก (เช่น--no-recursion, --exclude-tagฯลฯ ) ฉันกำลังมองหา --exclude-tagที่มีแนวโน้ม แต่ดูเหมือนจะตรงข้ามกับสิ่งที่ฉันกำลังมองหา
ateiob

ฉันลองแล้วเห็นว่าตัวละครถูกลบออกจากชื่อพา ธ ที่ยาว การใช้ tar กับ -T และ --null เป็น camh ที่เสนอหลีกเลี่ยงปัญหานี้
พอล Brannan

1
star -c -C startdir -find . ! -type d > out.tar

งด-C startdirและแทนที่.ด้วยstartdirหากควรปรากฏในที่เก็บถาวร

นี่เป็นวิธีที่มีประสิทธิภาพมากที่สุดตามคุณสมบัติของ libfind Libfind ยังนำเสนออุปกรณ์-chown -chgrp -chmodที่แก้ไข stat ให้เข้าที่และอนุญาตให้เก็บเมทาดาทาต่างๆ นอกจากนี้ยังใช้งานได้ในรายการและแยกโหมดและหลีกเลี่ยงความต้องการแยกไฟล์เก็บถาวรทั้งหมดในหลายกรณี


คุณสามารถใช้-findใน-copyโหมด สรุป man page แนะนำให้คุณทำได้ แต่ฉันไม่สามารถทำงานได้ (ในขณะที่พยายามตอบวิธีคัดลอกไฟล์ที่แก้ไขในขณะที่รักษาโครงสร้างโฟลเดอร์ ) (ด้วย schily-2016-02-10)
Stéphane Chazelas

ฉันไม่ได้ทดสอบสิ่งนี้เป็นเวลานาน อาจเป็นไปได้ว่าขณะนี้มีข้อผิดพลาด หน้าคนบอกว่าอาร์กิวเมนต์สุดท้ายจะเป็นไดเรกทอรีการแยก แต่เมื่อฉันลองนี้ฉันจะได้รับ: "อาร์กิวเมนต์เส้นทางที่ยังไม่ได้รับการสนับสนุนในโหมดแยก" นี่คือสิ่งที่คุณจะได้รับเมื่อคุณลอง
schily

ใช่. หน้าคนบอกว่าคุณสามารถหาข้อโต้แย้งหลังจาก - หา แต่ถ้าฉันใส่ไดเรกทอรีปลายทางก่อน - หาฉันยังได้รับข้อผิดพลาด
Stéphane Chazelas

มีรหัสเพื่อปิดการค้นหารหัสในกระบวนการแยกและข้อความแสดงข้อผิดพลาดมาจากการตรวจสอบที่ไม่ถูกต้องที่คาดว่า -c แต่ควรอนุญาต -copy ในโหมดคัดลอกตัวแยกวิเคราะห์ find ไม่ควรมีอาร์กิวเมนต์ล่าสุด
schily

1
ทางออกสุดท้ายได้รับการเผยแพร่ในเครื่องมือ schily ที่ sourceforge.net/projects/schilytools/files/schily-2016-03-11.tar.bz2 สิ่งนี้ยังช่วยแก้ไขปัญหาจาก setlocale () ที่หายไปในดาวและสิ่งนี้ช่วยให้ - C directrory star -findสำหรับ
schily

0

ฉันอาจพบวิธีแก้ปัญหา

find mydir -type f -printf '%P\0'|tar czvf mydir.tar.gz -C mydir --null -T -

สิ่งนี้อาจมีค่าใช้จ่ายเล็กน้อย แต่มันก็ใช้ได้ดีเพราะมันไม่ได้ขึ้นอยู่กับ xargs


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