ฉันจะลบไฟล์ทั้งหมดจากไดเรกทอรีเมื่อรายงานว่า "รายการอาร์กิวเมนต์ยาวเกินไป"


11

ฉันมีไดเรกทอรีที่มีไฟล์สองแสนไฟล์

ฉันต้องการลบไฟล์ทั้งหมด แต่รายงาน rm * -f: "รายการอาร์กิวเมนต์ยาวเกินไป"

วิธีที่ดีที่สุดในการล้างไดเรกทอรีนี้คืออะไร?


ที่เกี่ยวข้องซ้ำซ้อนกึ่ง: unix.stackexchange.com/questions/37329/…
Denilson Sá Maia

คำตอบ:


11

ในกรณีที่คุณไม่สามารถลบไดเรกทอรีคุณสามารถใช้ find

find . -maxdepth 1 -type f -exec rm -f {} \;

ที่จะลบไฟล์ทั้งหมดในไดเรกทอรีปัจจุบันและเฉพาะไดเรกทอรีปัจจุบัน (ไม่ใช่ไดเรกทอรีย่อย)


เกือบจะสมบูรณ์แบบ (ดูโพสต์ของฉันเกินไป)
asdmin

2
บน linux คุณสามารถทำได้เร็วยิ่งขึ้นโดยใช้ "+" แทน "\;" ที่จะทำให้มันลบไฟล์เพิ่มเติมต่อ "RM" ในครั้งเดียว
Thomas Thomas

5
เร็วยิ่งขึ้น: find dir/to/delete -delete(ไม่วางrmกระบวนการต่อไฟล์ที่จะลบ)
Morten Siebuhr

มอร์เทน: เขาไม่เคยเอ่ยถึงความต้องการที่จะลบไดเรกทอรีตัวเองใช่มั้ยเอ๋อพูดไฟล์ต่างๆ find dir/to/delete -type f -delete
richo

21
หา -maxdepth 1 -type f -exec rm -f {} \;

มันใช้เวลานานเกินไป (หนึ่ง exec ของ rm ต่อไฟล์)

อันนี้มีประสิทธิภาพมากขึ้น:

หา -maxdepth 1 -type f -print0 | xargs -r0 rm -f

ตามที่ใช้ชื่อไฟล์มากที่สุดเท่าที่เป็นไปได้เพื่อโต้แย้ง rm มากที่สุดแล้วรัน rm ด้วยชื่อไฟล์ที่โหลดถัดไป ... อาจเกิดขึ้นได้ว่า rm นั้นถูกเรียกเพียง 2 หรือ 3 ครั้ง


5
ดีใจที่ได้เห็นบางคนรู้ว่างานหาอย่างไร ... ลองพิจารณาด้วยคำสั่ง -delete action หรือคำสั่ง -exec ใหม่ {} + ของ gnu find ซึ่งทำหน้าที่เหมือน xargs ดูส่วนการกระทำของ 'ค้นหาคน'
Kyle Brandt

ฉันไม่รู้เกี่ยวกับ -exec cmd {} + มันดูมีประโยชน์ทีเดียว เล็กน้อยทั่วไปกว่าการลบ :)
เดวิด Pashley

-delete อาจไม่เป็นไร แต่โดยส่วนตัวแล้วฉันชอบคำสั่งที่สามารถใช้ได้กับเครื่องที่หลากหลาย ระบบ Solaris ที่ฉันทำงานด้วยนั้นเก่ากว่าดังนั้น -delete จะไม่สามารถใช้งานได้
asdmin

2
การเพิ่มไว้ioniceก่อนrmเป็นความคิดที่ดีถ้าผู้อื่นใช้คอมพิวเตอร์ในเวลาเดียวกัน
Hubert Kario

6

ทั้งสองอย่างนี้จะทำให้เกิดปัญหา มีการวิเคราะห์ผลการดำเนินงานที่เกี่ยวข้องของแต่ละเทคนิคมากกว่าคือที่นี่

find . -name WHATEVER -exec rm -rf {} \;

หรือ

ls WHATEVER | xargs rm -rf

ปัญหาเกิดจากการทุบตีขยาย "*" ด้วยทุก ๆ รายการในไดเรกทอรี โซลูชันทั้งสองนี้ทำงานผ่านแต่ละไฟล์แทน


2
วิธีการแก้ปัญหาการค้นหานั้นช้ากว่าไฟล์จำนวนมากเพราะจะเรียกใช้คำสั่ง rm สำหรับไฟล์ทุกไฟล์ โซลูชัน xargs นั้นเร็วกว่า แต่จะใช้ได้เฉพาะเมื่อชื่อไฟล์ไม่มีช่องว่าง (มิฉะนั้นคุณต้องใช้ GNU find และfind . -print0 | xargs -0 rm)
robcast

"find. -name WHATEVER -print0 | xargs -0 rm -rf" จะมีประสิทธิภาพมากขึ้น find จะแยก rm สำหรับทุกไฟล์โดยที่ xargs จะลดให้เหลือน้อยที่สุด คุณต้องการ -print0 และ -0 เพื่อจัดการกับไฟล์ที่มีช่องว่างคุณอาจต้องการใช้ -depth ใน find ดังนั้นจึงทำการค้นหาในเชิงลึกก่อน
David Pashley

คำสั่งคำสั่ง ls จะไม่ทำงานเช่นที่มากเกินไปจะส่งกลับ "รายการอาร์กิวเมนต์ยาวเกินไป"
เบรนท์

2
คุณกำลังทำ " ls *" และ " *" ขยายไปยังรายการอาร์กิวเมนต์ที่เชลล์ของคุณบ่นว่ายาวเกินไป ทำ " ls ." แทน (หรือขึ้นไปหนึ่งระดับไดเรกทอรีและทำ " ls [dirname]")
James Sneeringer

บรรทัดคำสั่งที่สอง (ls WHATEVER | xargs rm -rf) จะไม่ทำงานด้วยเหตุผลเดียวกับคำถามที่ใช้งานไม่ได้: WHATEVER จะถูกแทนที่ด้วยเชลล์ให้มีความยาวเกิน
asdmin

3

ฉันสามารถทำได้โดยสำรองหนึ่งระดับ:

cd ..

และวิ่ง:

rm directory name -rf

จากนั้นสร้างไดเรกทอรีขึ้นใหม่


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

2

การค้นหาการเรียกใช้ทั้งหมดเหล่านี้เป็นสิ่งที่ดีมาก แต่ฉันแทบจำไม่ได้ว่าระบบการตั้งชื่อที่จำเป็นเมื่อฉันรีบ: ฉันใช้ ls แทน ในฐานะที่เป็นคนกล่าวถึง ls จะทำงาน แต่ฉันชอบ ls -1 เช่นเดียวกับใน:

ls -1 | xargs -n 100 rm -rf

รูป -n xxx นั้นค่อนข้างปลอดภัยที่จะเล่นโดยมีค่าเกินจำนวนสูงสุดจะได้รับการแก้ไขอัตโนมัติ (ถ้าเกินขนาดสูงสุด, ดู -s) หรือ args-max สำหรับแอปนั้นเกินปกติ ชัดเจน.

ควรสังเกตว่า grep มีประโยชน์ในการแทรกตรงกลางของเชนนี้เมื่อคุณต้องการลบไฟล์ย่อยในไดเร็กตอรี่ขนาดใหญ่, และไม่ว่าด้วยเหตุผลใดก็ตามที่ต้องการใช้ find.

คำตอบนี้สมมติว่าคุณกำลังใช้ยูทิลิตีหลักของ Gnu สำหรับ ls, xargs & ฯลฯ


สิ่งนี้จะทำงานกับไดเรกทอรีที่ใหญ่เกินไปสำหรับ "ls" หรือไม่ (ข้อผิดพลาดเดียวกัน - รายการการโต้เถียงยาวเกินไป)
เบรนต์

ใช่เบรนต์: อย่าใช้ filespec เมื่อเรียกใช้ ls ใช้ -1 (เส้นประหนึ่ง) ตามที่แสดงด้านบน และตามที่อธิบายไว้ข้างต้นใช้ grep หลังจาก ls หากคุณต้องการจับคู่รายการไฟล์ หากคุณได้รับข้อผิดพลาด "ยาวเกินไป" หลังจากตรวจสอบให้แน่ใจว่าคุณไม่ได้ใช้สัญลักษณ์แทนด้วย ls แสดงว่า xargs กำลังบ่นอยู่ ใช้ 'xargs -n 5' แทน 'xargs -n 100' และคุณควรจะปลอดภัยแน่นอนถ้าช้าลงเล็กน้อย
rixtertech

1

คุณสามารถใช้-exec +ตัวเลือกเพื่อค้นหาว่าจะลองใช้ rm สองสามครั้งเท่าที่จะทำได้ซึ่งอาจเร็วกว่า

find . -type f -exec rm '{}' +

0

นี่คือเวอร์ชันสำหรับการลบไฟล์จำนวนมากเมื่อระบบต้องการตอบสนอง

มันทำงานได้โดยการออกงานเป็นชุดเล็ก ๆ (100 ไฟล์โดยค่าเริ่มต้น) และรอสักครู่เพื่อให้งานอื่นให้เสร็จ

ทำงานได้อย่างยอดเยี่ยมสำหรับการลบไฟล์กว่าครึ่งล้านไฟล์จากไดเรกทอรีเดียวบน ext3 มันพิมพ์เปอร์เซ็นต์ที่ทำเป็นโบนัสเล็กน้อย

noOfFiles=`ls -U | wc -l`
n=0
while (ls -U | tail -n 100 | xargs rm -f); do 
   n=$((n+100));
   sync;
   echo -en "$((n*100/noOfFiles))%, ($n of $noOfFiles)\r";
   sleep 5;
done

0

แก้ไขข้อผิดพลาด "อาร์กิวเมนต์ยาวเกินไป" หรือ "ไม่สามารถจัดสรรหน่วยความจำ"

นี่เป็นการหลอกลวงสำหรับไฟล์ 220,000+ ไฟล์ในโฟลเดอร์เซสชั่น ....

ข้อได้เปรียบ: เริ่มลบไฟล์ทันที

เส้นทางซีดี / ถึง / โฟลเดอร์
ls -f | xargs rm -f -v

คลิกเพื่อลบภาพหน้าจอของไฟล์ - (ลบไฟล์ทั้งหมดใน ~ 15 นาที)

-f (หลังจาก ls)ป้องกันการเรียงลำดับล่วงหน้า

-v (หลังจาก rm)แสดงแต่ละไฟล์ว่าถูกลบ

-f (หลังจาก rm)บังคับให้ผ่านโดยไม่มีพรอมต์สำหรับไฟล์ที่ป้องกันการเขียน

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


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