ลบทั้งหมดยกเว้น 1,000 ไฟล์สุ่มในไดเรกทอรี


13

ฉันปล่อยให้สคริปต์การสร้างข้อมูลทำงานนานเกินไปตอนนี้มีไฟล์มากกว่า 200,000 ไฟล์ซึ่งฉันต้องการลดลงเหลือประมาณ 1,000 ไฟล์จากบรรทัดคำสั่ง Linux มีวิธีที่ง่ายในการลบทั้งหมดยกเว้นไฟล์เหล่านี้ 1,000 ไฟล์โดยที่ไฟล์ที่จะถูกเก็บไว้ จะไม่มีการพึ่งพาชื่อไฟล์หรือคุณลักษณะอื่น ๆ


กระบวนการที่สร้างไฟล์มีคุณสมบัติที่เกี่ยวข้องกับแต่ละไฟล์กับไฟล์ก่อนหน้าหรือไม่? ถ้าเป็นเช่นนั้นการเลือกแบบสุ่มจะเป็นสิ่งสำคัญที่จะได้รับตัวอย่างตัวแทน หากกระบวนการสร้างไฟล์ที่สุ่มโดยธรรมชาติคุณสามารถลบทุกอย่างหลังจาก 1000 ไฟล์แรกได้
fixer1234

คำตอบ:


15

ลบทั้งหมดยกเว้น 1,000 ไฟล์สุ่มในไดเรกทอรี

รหัส:

find /path/to/dir -type f -print0 | sort -zR | tail -zn +1001 | xargs -0 rm

คำอธิบาย:

  1. รายการไฟล์ทั้งหมด/path/to/dirด้วยfind;
    • print0: use \0( อักขระ null ) เป็นตัวคั่นบรรทัด; ดังนั้นเส้นทางของไฟล์ที่มีช่องว่าง / การขึ้นบรรทัดใหม่จะไม่ทำให้สคริปต์แตก
  2. สลับรายการไฟล์ด้วยsort;
    • -z: use \0(อักขระ null) เป็นตัวคั่นแทน\n(ขึ้นบรรทัดใหม่)
    • -R: ลำดับแบบสุ่ม
  3. ตัด 1,000 บรรทัดแรกจากรายการที่สุ่มด้วยtail;
    • -z: ถือว่ารายการเป็นศูนย์ที่คั่นด้วย (เช่นเดียวกับsort)
    • -n +1001: แสดงบรรทัดที่เริ่มต้นจาก 1001 (เช่นละเว้นบรรทัดแรก 1000)
  4. xargs -0 rm - ลบไฟล์ที่เหลือ;
    • -0: คั่นด้วยศูนย์อีกครั้ง

ทำไมมันดีกว่าทางออกของ quixotic *:

  1. ทำงานกับชื่อไฟล์ที่มีช่องว่าง / บรรทัดใหม่
  2. อย่าพยายามสร้างไดเรกทอรีใด ๆ (ซึ่งอาจมีอยู่แล้ว btw.)
  3. ไม่ได้ย้ายไฟล์ใด ๆ ที่ไม่ได้แตะ 1000 "ไฟล์โชคดี" findนอกเหนือจากรายชื่อพวกเขาด้วย
  4. หลีกเลี่ยงไฟล์ที่หายไปในกรณีที่ผลลัพธ์ของfindไม่ได้ลงท้ายด้วย\n(ขึ้นบรรทัดใหม่) ด้วยเหตุผลบางประการ

* - เครดิตสำหรับเพ้อฝันสำหรับ| sort -R | head -1000ทำให้ฉันเป็นจุดเริ่มต้น


ทำงานบน CentOS 6 ฉันได้รับข้อผิดพลาดเกี่ยวกับตัวถูกดำเนินการที่ไม่ถูกต้อง โชคดีที่ผมไม่ได้เกี่ยวข้องกับช่องว่างใน filepaths ดังนั้นการลบตัวถูกดำเนินการผู้ที่ทำงานให้ฉันfind . -type f | sort -R | tail -n +1001 | xargs rm
แบรด

@brad คุณสามารถให้ข้อความแสดงข้อผิดพลาดและรุ่นของfindคุณได้หรือไม่ ฉันจะพยายามปรับปรุงคำตอบของฉันเพียงแค่ต้องการอินพุตเพื่อทำงานกับ
rld

3
tail: invalid option -- 'z'รุ่นหางที่ฉันมีคือ 8.4
แบรด

ฉันจะเพิ่ม - no-run-if-empty เพื่อ xargs เพื่อหลีกเลี่ยงข้อผิดพลาดหากไม่มีไฟล์ (หลังจากใช้งานสองครั้งเพื่อเป็นตัวอย่าง)
21919

1

ใช้ไดเรกทอรีชั่วคราวจากนั้นfindไฟล์ทั้งหมดของคุณสุ่มรายการด้วยsortและย้าย 1,000 รายการแรกไปยังไดเรกทอรีชั่วคราว ลบที่เหลือแล้วย้ายไฟล์กลับจากไดเรกทอรีชั่วคราว

$ mkdir ../tmp-dir
$ find . -type f | sort -R | head -1000 | xargs -I "I" mv I ../tmp-dir/
$ rm ./*
$ mv ../tmp-dir/* .

ถ้าxargsบ่นเกี่ยวกับความยาวเส้นใช้จำนวนขนาดเล็กที่มีheadและทำซ้ำคำสั่งตามความจำเป็น (เช่นการเปลี่ยนแปลง-1000ไป-500และเรียกใช้มันสองครั้งหรือการเปลี่ยนแปลงไป-200และเรียกใช้ 5 ครั้ง.)

มันจะล้มเหลวในการจัดการชื่อไฟล์ที่มีช่องว่าง เป็น@ rld ของคำตอบที่แสดงให้เห็นว่าคุณสามารถใช้find's -print0อาร์กิวเมนต์ที่-zข้อโต้แย้งsortและheadและ-0มีxargsเพื่อให้แน่ใจว่าการจัดการชื่อไฟล์ที่เหมาะสม

ท้ายที่สุดถ้าtmp-dirมีอยู่แล้วคุณควรแทนที่ชื่อไดเรกทอรีที่ไม่มีอยู่


สิ่งนี้จะล้มเหลวหากชื่อไฟล์ใด ๆ ที่ระบุโดยfindมีช่องว่าง
rld

0

สำหรับผู้ใช้ mac สคริปต์ต่อไปนี้ควรทำ

find . -type f -print0 | tr '\0' '\n' | sort -R | tail -n +10000 | tr '\n' '\0' | xargs -0 rm

trจะช่วยให้การจัดเรียงและหางในการทำงานเกี่ยวกับรายการที่มีแทน\n\0


-2

วิธีที่ง่ายที่สุดอาจเป็น rm -rf ไดเรกทอรีจากนั้นเรียกใช้สคริปต์การสร้างข้อมูลอีกครั้งในขณะที่แน่ใจว่าจะไม่ทำงานนานเกินไป


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