ฉันจะลบไฟล์ทั้งหมดในโฟลเดอร์ยกเว้นไฟล์ที่ระบุได้อย่างไร


11

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

ตัวอย่างเช่นชื่อไฟล์ที่ฉันต้องการเก็บคือ:

file_1.png, another_file.jpg,some_music.mp3

คำตอบ:


15

หากคุณใช้ทุบตี:

shopt -s extglob
rm -- !(file1|file2|file3)

บรรทัดแรกเปิดใช้งานการจับคู่รูปแบบเพิ่มเติมและหลังจากนั้นเราใช้หนึ่งในนั้น:

!(pattern-list) จับคู่อะไรก็ได้ยกเว้นหนึ่งในรูปแบบที่กำหนด

|และรูปแบบรายการคือรายการหนึ่งหรือมากกว่าหนึ่งรูปแบบคั่นด้วย


หรือด้วย zsh

setopt extendedglob
rm -- ^(file1|file2)

หรือพกพาได้มากกว่าโดยใช้find:

find . -maxdepth 1 ! -name 'file1' ! -name 'file2' -type f -exec rm -v {} +

3
อาจเป็นประโยชน์ในการรวมวิธีคืนค่าลักษณะการทำงานเชลล์ที่เป็นทางเลือกกลับมา ( shopt -u extglob)
geedoubleya

7

สร้างไดเรกทอรีย่อยtmpย้ายไฟล์ทั้งหมดที่คุณต้องการเก็บไว้ในไดเรกทอรีนั้นและทำrm -f *หลังจากนั้น ที่จะไม่ส่งผลกระทบต่อtmpไดเรกทอรี

หลังจากนั้นเพียงทำ:

mv tmp/* .
rmdir tmp

(สมมติว่าไม่มีไฟล์ใดที่คุณย้ายเริ่มต้นด้วยจุด)

นี่เป็นหนึ่งในไม่กี่กรณีที่เหมาะสมที่จะใช้เมาส์และเบราว์เซอร์ไฟล์เช่น Nautilus ที่คุณสามารถ - Ctrlคลิกที่ไฟล์ที่คุณต้องการเก็บไว้แล้วใช้เมนู: Edit -> Invert Selectionเพื่อรับไฟล์อื่นแล้วลบไฟล์เหล่านั้น .


ย้ายไฟล์ไปยังไดเรกทอรี tmp ฟังดูดี อย่างไรก็ตามฉันต้องทำด้วยบรรทัดคำสั่ง ขอบคุณ!
AGamePlayer

3
@AwQiruiGuo tmp มีข้อได้เปรียบที่จะแยกไฟล์ออกเป็นสองชุดก่อนที่จะทำการลบไฟล์ที่คุณไม่ต้องการออกไปอย่างถาวร ดังนั้นคุณสามารถเรียกใช้lsเพื่อดูว่าคุณไม่ได้พลาดไฟล์ใด ๆ ที่คุณต้องการรักษา
Anthon

2

เพิ่มชื่อของไฟล์ที่คุณต้องการเก็บไว้ในไฟล์ข้อความหนึ่งชื่อต่อบรรทัด ไฟล์นี้ไม่ควรอยู่ในไดเรกทอรีหรือคุณควรเพิ่มชื่อด้วย

หากชื่อไดเรกทอรีของคุณเป็นfooและชื่อของไฟล์คือแถบให้ทำดังต่อไปนี้

find foo -type f -print0|grep -vzZ -f bar|xargs -0 rm

นี่ทำสิ่งต่อไปนี้:

  1. find -type fค้นหาชื่อของไฟล์ทั้งหมดในfooและไดเรกทอรีย่อยและพิมพ์ไปยัง STDOUT ด้วยตัวเลือก-print0มันจะแยกชื่อไฟล์ด้วย NUL ไบต์
  2. grep -v -f barไม่รวมชื่อไฟล์ทั้งหมดที่ตรงกับสายในบาร์ ด้วยตัวเลือก-zมันปฏิบัติกับการป้อนข้อมูลของมันเป็นชุดของเส้นที่คั่นด้วย NUL ไบต์ด้วยตัวเลือกที่-Zมันจะเอาท์พุทที่มีไบต์ NUL
  3. xargs rmโทรrmซ้ำ ๆ เพื่อลบไฟล์ ด้วยตัวเลือก-0มันจะถือว่าอินพุตเป็นชุดของเส้นที่คั่นด้วย NUL ไบต์

ใช้งานได้กับชื่อไฟล์ที่มีช่องว่าง


สิ่งนี้จะไม่ทำงานเนื่องจากชื่อไฟล์สามารถมีการขึ้นบรรทัดใหม่ได้
Anthon

@Athon เปลี่ยนตัวเลือกของ find, grep, xargs เพื่อจัดการกับชื่อไฟล์ที่มีช่องว่างรวมถึงการขึ้นบรรทัดใหม่
Mathias Weidner

ถ้าคุณต้องการใช้findฉันอยากจะทำfind . -maxdepth 1 ! -name 'file1' ! -name 'file2' -type f -exec rm -vi {} +
jimmij
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.