foo
ฉันต้องการที่จะลบไฟล์ทั้งหมดที่มีสตริง ฉันจะทำสิ่งนี้โดยใช้ bash ใน Linux ได้อย่างไร
foo
(เช่นmyfoo.jpg
) หรือไฟล์ที่มีลำดับไบต์foo
(ซึ่งอาจรวมถึงไฟล์ไบนารีที่เกิดขึ้นเพื่อให้มีลำดับไบต์นั้น)
foo
ฉันต้องการที่จะลบไฟล์ทั้งหมดที่มีสตริง ฉันจะทำสิ่งนี้โดยใช้ bash ใน Linux ได้อย่างไร
foo
(เช่นmyfoo.jpg
) หรือไฟล์ที่มีลำดับไบต์foo
(ซึ่งอาจรวมถึงไฟล์ไบนารีที่เกิดขึ้นเพื่อให้มีลำดับไบต์นั้น)
คำตอบ:
นี่คือวิธีที่ปลอดภัย:
grep -lrIZ foo . | xargs -0 rm -f --
-l
พิมพ์ชื่อไฟล์ของไฟล์ที่ตรงกับรูปแบบการค้นหา-r
ดำเนินการค้นหา recursive สำหรับรูปแบบในไดเรกทอรีที่กำหนดfoo
หากยังไม่สามารถทำงานให้ลอง.
-R
-I
(ตัวพิมพ์ใหญ่i
) ทำให้ไฟล์ไบนารีเช่น PDF ถูกข้าม-Z
ตรวจสอบให้แน่ใจว่าชื่อไฟล์เป็นศูนย์ - (เช่น nul-) ถูกยกเลิกเพื่อให้ชื่อที่มี white space ไม่ได้รับการตีความในทางที่ผิด (เช่นเป็นชื่อหลาย ๆ ชื่อแทนที่จะเป็นชื่อเดียว)xargs -0
ฟีดชื่อไฟล์จากgrep
ถึงrm -f
โดยแยกคำด้วยศูนย์ (nul) ไบต์ (จำ-Z
ตัวเลือกจากgrep
)--
มักจะถูกลืม -
แต่มันก็เป็นสิ่งที่สำคัญมากในการทำเครื่องหมายจุดสิ้นสุดของตัวเลือกและอนุญาตให้มีการกำจัดของไฟล์ที่มีชื่อขึ้นต้นด้วยหากคุณต้องการที่จะเห็นไฟล์ที่กำลังจะถูกลบออกเพียงแค่เอา| xargs -0 rm -f --
ส่วนหนึ่งและปล่อยให้ปิดตัวเลือกในการZ
grep
ผู้ใช้รายอื่นแนะนำสิ่งต่อไปนี้ซึ่งคุณไม่ควรเรียกใช้เพราะไม่ปลอดภัย:
files=`grep foo * | cut -d: -f1`
rm -f $files # unsafe, do not run it!
หากฉันมีไฟล์ImportantStuff
ที่ฉันไม่ต้องการลบและobsolete ImportantStuff
มีอยู่foo
ฉันจะสูญเสียImportantStuff
(และไม่ obsolete ImportantStuff
!) เมื่อฉันเรียกใช้คำสั่งนี้เพราะ$files
แยกออกจากกันที่ช่องว่างเมื่อมีการตีความ การใส่รายชื่อไฟล์ลงในตัวแปรสเกลาร์เชลล์เป็นสิ่งที่อันตราย
$ find -type f -exec grep -q "foo" {} \; -exec echo rm -- {} \;
วิธีนี้จะค้นหาไฟล์ที่มีfoo
ซ้ำ ๆ ที่สอง-exec
จะทำงานก็ต่อเมื่อการexec
ออกครั้งแรกประสบความสำเร็จเช่นถ้าgrep
ตรงกัน Dryrun และลบecho
ถ้าผลลัพธ์ดูเหมือนว่าถูกต้อง
หรืออีกวิธีหนึ่ง
$ find -type f -exec grep -q "foo" {} \; -print
และ
$ find -type f -exec grep -q "foo" {} \; -delete
ตามที่แนะนำโดย Lekensteyn
find -type f -exec grep -q 'foo' {} \; -delete
(เครื่องหมายคำพูดรอบ ๆ{}
ซ้ำซ้อนfind
สามารถลบไฟล์ได้ด้วย) โปรดทราบว่าgrep
ยอมรับการแสดงออกปกติ หากคุณต้องการค้นหาให้foo.bar
หลีกเลี่ยงสิ่งนี้หรือส่ง-F
ตัวเลือกเพื่อรักษารูปแบบตามตัวอักษร
-exec echo rm "{}" \;
และไม่-delete
?
-delete
ไม่ฉันต้องการใช้ มันง่ายกว่าที่จะสาธิตด้วยเสียงที่สอง-exec
และสะท้อนเสียง
-print
(หรือสำหรับฟุ่มเฟื่อยมากขึ้นกว่า)-ls
-exec echo rm "{}" \'
ไม่จำเป็นต้องมียูทิลิตี้ภายนอก
ฉันจะทำสิ่งที่เอเดรียนพูด
แต่ฉันจะเพิ่มขอบเขตของคำเพื่อไม่ให้ลบไฟล์ที่มีคำว่า "อาหาร" (เว้นแต่จะเป็นการลบทุกอย่างที่มีอาหารเป็นสิ่งที่คุณต้องการ)
$ find -type f -exec grep -q "\<foo\>" {} \; -delete
ฉันจะเปลี่ยนเส้นทางผลลัพธ์ก่อนที่จะลบดังนั้นฉันสามารถตรวจสอบก่อนที่จะลบ:
$ find -type f -exec grep -q "\<foo\>" > /tmp/list_of_files_to_delete