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


123

ฉันต้องการลบไฟล์ทั้งหมดในไดเรกทอรี แต่ไม่รวมบางไฟล์ ยกตัวอย่างเช่นในไดเรกทอรีที่มีไฟล์ที่a b c ... zผมจำเป็นต้องลบทั้งหมดยกเว้นและu pมีวิธีง่าย ๆ ในการทำเช่นนี้?


คำตอบด้านล่างนั้นดีกว่ามาก แต่คุณสามารถสร้างไฟล์เพื่อบันทึกแบบอ่านอย่างเดียวลบทั้งหมดแล้วเปลี่ยนกลับเป็นสิทธิ์ดั้งเดิม (ตราบใดที่คุณไม่ได้ใช้ rm -f) คุณต้องรู้ว่าต้องใช้การอนุญาตใดในการกู้คืนและคุณต้องรู้ว่าไม่จำเป็นต้องมีสิทธิ์การเข้าถึงเพื่อเขียนในระหว่างกระบวนการ นี่คือเหตุผลที่คำตอบอื่น ๆ ดีกว่า
Joe

1
หากคุณยังต้องการที่จะลบไฟล์ที่ซ่อนอยู่เรียกใช้ก่อนที่จะใช้shopt -s dotglob rm (...)

คำตอบ:


108

สิ่งที่ฉันทำในกรณีเหล่านั้นคือการพิมพ์

rm *

จากนั้นผมก็กดCtrl+ X, *การขยาย *เข้าไปในชื่อไฟล์ทั้งหมดที่มองเห็น

จากนั้นฉันสามารถลบสองไฟล์ที่ฉันต้องการเก็บไว้จากรายการและดำเนินการบรรทัดคำสั่งในที่สุด


25
ฉันเดาว่ามันใช้งานได้ตราบใดที่รายชื่อไฟล์ที่*ขยายตัวนั้นยาวเกินไป : -}
Frerich Raabe

9
Esc ตามด้วย * จะขยาย "*"
slowpoison

2
@SantoshKumar: นั่นไม่สมเหตุสมผลกับฉัน การขยายจะใช้งานได้เสมอโดยไม่ขึ้นอยู่กับคำสั่งที่คุณต้องการใช้ในภายหลัง
Der Hochstapler

2
@OliverSalzburg ขออภัยการรวมกันค่อนข้างสับสน ฉันคิดว่าคุณควรเขียนเช่นCtrl+ Shift+ x+*
Santosh Kumar

2
@SantoshKumar: แต่นั่นไม่ใช่การรวมกัน
Der Hochstapler

143

ไปที่rmทั้งหมดยกเว้นu,pใน bash เพียงแค่พิมพ์:

rm !(u|p)

สิ่งนี้ต้องมีการตั้งค่าตัวเลือกต่อไปนี้:

shopt -s extglob

ดูเพิ่มเติม: glob - Wiki ของ Greg


1
คุณต้องเปิดใช้งาน 'extglobbing': shopt -s extglob
sparkie

18
คุณต้องshopt -s extglob@Ashot นอกจากนี้ยังเป็นเพียงไฟล์ไม่ใช่ไดเรกทอรีซึ่งเป็นสาเหตุที่ฉันได้ลบ-rfตัวเลือกในคำสั่งของคุณ
slhck

3
หากคุณจำเป็นต้องยกเว้นไฟล์เดียวของการเลือกrm !(index).htmlไฟล์ลองนี้ การดำเนินการนี้จะลบไฟล์ทั้งหมดที่ลงท้ายด้วย ".html" ยกเว้น "index.html"
mzuther

71

คุณสามารถใช้ได้ find

find . ! -name u ! -name p -maxdepth 1 -type f -delete
  • ! ปฏิเสธนิพจน์ถัดไป
  • -name ระบุชื่อไฟล์
  • -maxdepth 1จะทำให้กระบวนการค้นหาไดเรกทอรีที่ระบุเท่านั้น ( findโดยเริ่มต้นไดเรกทอรีสำรวจ)
  • -type f จะประมวลผลไฟล์เท่านั้น (และไม่ใช่สำหรับไดเรกทอรีตัวอย่าง)
  • -delete จะลบไฟล์

จากนั้นคุณสามารถปรับเงื่อนไขการค้นหาหน้าคนค้นหา

ปรับปรุง

  • โปรดทราบว่าลำดับขององค์ประกอบของนิพจน์นั้นมีความสำคัญ (ดูเอกสารประกอบ)
  • ทดสอบคำสั่งของคุณก่อนโดยใช้-printแทน-delete

    find . ! -name u ! -name p -maxdepth 1 -type f -print

5
คำสั่งของภาคแสดงเป็นสิ่งสำคัญที่นี่ หากหนึ่งใส่-deleteหลังจาก.นั้นจะเป็นภัยพิบัติ (จะลบไฟล์ทั้งหมดใน CWD)
Michał Michrajer

สิ่งนี้สามารถเขียนได้อย่างกระชับมากขึ้นเมื่อfind . -maxdepth 1 -type f -name '[^up]' -delete
kojiro

4
@kojiro ใช่ แต่สำหรับไฟล์ที่มีเพียงตัวอักษรเดียว ด้วยชื่อที่ซับซ้อนมากขึ้น regex อาจเป็นระเบียบ
Matteo

2
findเป็นเพื่อนที่ดีที่สุดของฉันโดยเฉพาะอย่างยิ่งเมื่อมีไฟล์จำนวนมากเกินกว่าจะกู้ได้
Terence Johnson

43

ง่าย:

mvไฟล์ที่คุณต้องการในไดเรกทอรีด้านบนrmไดเรกทอรีและmvพวกเขากลับมา


13
นอกหลักสูตร mv พวกเขาไปยังไดเรกทอรีที่สูงขึ้น พยายามที่จะไม่ให้พวกเขา mv ไดเรกทอรีย่อยคุณลบ ...
Konerak

@Konerak: rmไม่มี-rจะไม่ลบไดเรกทอรีย่อย
reinierpost

11
ซึ่งจะเขียนทับไฟล์ที่มีชื่อเดียวกันในไดเรกทอรีปลายทาง
Matteo

7
ฉันกำลัง downvoting นี้เพราะในขณะที่มันสามารถเป็นประโยชน์ก็ยังไม่ปรมาณูและมีประสิทธิภาพลบไฟล์ทั้งหมดจากไดเรกทอรีในช่วงเวลาสั้น ๆ ; สิ่งนี้จะไม่เป็นที่ยอมรับหากมีการแชร์ไฟล์บนเครือข่าย
sam hocevar

15

ค่อนข้างคล้ายกับคำตอบนี้แต่ไม่จำเป็นต้องมีตัวเลือกพิเศษเท่าที่ฉันรู้ต่อไปนี้คือฟังก์ชั่น "โบราณ" ที่สนับสนุนโดยใด ๆ (ราง) / bin / sh คล้ายเปลือก (เช่นทุบตี, zsh, ksh, ฯลฯ )

rm [^up]

2
ใช้งานได้กับชื่อไฟล์แบบ 1 ถ่าน สำหรับชื่อที่ยาวขึ้นคำตอบของ sparkie ดีกว่า
เกล็

3
อะไรจะมีความผิดด้วยrm [^up]*? ฉันทำสิ่งที่คล้ายกันค่อนข้างบ่อย
CVn

3
@ MichaelKjörling - สิ่งนี้จะลบไฟล์ทั้งหมดที่ขึ้นต้นด้วย u หรือ p ไม่ใช่เฉพาะไฟล์ที่มีชื่อ u และ p ฉันคิดว่า OP (@Ashot) หมายถึง az และ u, p ฯลฯ เป็นสัญลักษณ์และไม่แท้จริง
Sudipta Chatterjee

4
@HobbesofCalvin ที่จะลบไฟล์ทั้งหมดที่ไม่ได้ขึ้นต้นด้วย u หรือ p ไม่ใช่ไฟล์ที่ขึ้นต้นด้วย
rjmunro

@rjmunro - ขอบคุณที่พลาดไป! :)
Sudipta Chatterjee

11

ทำโดยไม่ต้องค้นหา:

ls | grep -v '(u|p)' | xargs rm

(แก้ไข: "u" และ "v" เช่นเดียวกับที่อื่น ๆ ที่นี่ถูกใช้เป็น regexes เวอร์ชันทั่วไปแน่นอนคุณจะต้องระวังที่จะยึด regexes ของคุณเพื่อหลีกเลี่ยงการจับคู่สิ่งต่าง ๆ มากเกินไป)

แน่นอนคุณจะต้องการสคริปต์ถ้าคุณจะทำสิ่งนี้มากตามที่คนอื่นแนะนำ


grep จะไม่จัดการ regexpt แบบขยายโดยค่าเริ่มต้น: ใช้-Eหรือegrep
Matteo

2
สิ่งนี้จะไม่รวมไฟล์ใด ๆ ที่มีuหรือp
ตเตโอ

@Matteo ไม่ได้ grep ไม่ทำการ grepping ไฟล์มัน grepping ผลลัพธ์ของคำสั่ง ls คุณกำลังคิดถึงบางสิ่งเช่นgrep -L (u|p)' * | xargs rmที่-Lหมายถึงรายชื่อไฟล์ที่ไม่มีการจับคู่
rjmunro

4
โอ้คุณหมายถึงไฟล์ที่มีชื่อใด ๆuหรือpไม่ไฟล์ใด ๆ ที่มีหรือu pถูกต้อง. คุณสามารถแก้ไขได้โดยใช้egrep -v '^(u|p)$'
rjmunro

1
นี่คือลบทุกอย่างยกเว้นการแข่งขันเหล่านี้! ls | grep -v 'vuze\|progs' | xargs rm -rf
Nick

6

ใน zsh:

setopt extended_glob  # probably in your .zshrc

แล้วก็

rm ^(u|p)

หรือ

rm *~(u|p)

ที่สองจะทำงานแม้ว่าคุณจะมี^ใน$histcharsเพื่อทดแทนประวัติศาสตร์และแน่นอนคุณสามารถใส่ glob ~พลก่อน


5

GLOBIGNORE รับรายการที่คั่นด้วยโคลอน

GLOBIGNORE=u:p
rm *

12
สิ่งนี้ใช้ไม่ได้กับเชลล์ของฉัน (GNU bash 4.1.5 (1)) อย่าลืมทดสอบก่อนด้วยบางสิ่งที่อันตรายน้อยกว่าrmหรือในไดเรกทอรีทดสอบ!
CVn

3

ย้อนกลับไปในยุคฟลอปปี้ฉันมีไฟล์เรียกทำงาน DOS ที่เรียกว่า "ยกเว้น" ที่จะย้ายสิ่งต่าง ๆ ออกจากไดเรกทอรีปัจจุบันชั่วคราวและรันคำสั่งดังนั้นคุณสามารถพูดได้ว่า:

ยกเว้น * .txt del *. *

เพื่อลบทุกอย่างยกเว้นไฟล์ข้อความของคุณ

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


2
มันทำให้ฉันนึกถึงสิ่งเดียวกัน แต่ชั่วคราวย้ายออกจากโฟลเดอร์ที่ไม่อาจจะเป็นความคิดที่ดีในยุคของการทำงานแบบ multitasking :)
Sedat Kapanoglu

3
 find . -maxdepth 1 ! -name "u" ! -name "p" -type f -exec rm -rf {} \;

นี่จะลบไฟล์ทั้งหมดยกเว้น u และ p ในยูนิกซ์


2

สำหรับผู้ที่ต้องการระบุรูปแบบที่ไม่รวมตามอำเภอใจ (ซึ่งครอบคลุมชื่อไฟล์ที่ได้รับผลกระทบทั้งหมด) ในรูปแบบ emac regexp แบบเต็มรูปแบบ posix-awk หรือรูปแบบที่ขยายเพิ่มเติม (ดูหน้าค้นหาคน) ฉันอยากจะแนะนำรูปแบบนี้ มันไม่รวมuและpใน dir ปัจจุบันในตัวอย่างนี้ สิ่งนี้อาจเป็นประโยชน์สำหรับสคริปต์

find -regextype posix-awk ! -regex './(u|p)' -print0 | xargs -0 rm -rf

คุณต้องระบุไดเรกทอรีก่อนนิพจน์ (`find. -regextype ... )
Matteo

-regextypeจะทำงานกับรุ่น GNU เท่านั้น
Matteo

ไม่มี - รุ่น Find My (บีบเดเบียน) ไม่แตกหักไม่จำเป็นต้องไดเรกทอรีอย่างชัดเจนก่อนที่จะแสดงออกถ้าไดเรกทอรีปัจจุบันควรจะใช้
sparkie

@sparke: สิ่งนี้ใช้ได้กับการนำไปใช้ของ GNU
Matteo

@sparkie: ไม่ได้กำหนดไดเรกทอรี (พารามิเตอร์แรก) สำหรับfindเป็นส่วนขยายของfindคำสั่งGNU เช่นเดียวกับ-regextypeตัวเลือก นอกจากนี้คำสั่งของคุณจะลบไฟล์ในไดเรกทอรีย่อยด้วยเช่นกันในขณะที่คำถามเดิมถามอย่างชัดเจนเกี่ยวกับไฟล์ในไดเรกทอรี
Mikko Rantalainen

1

ฉันมักจะใช้:

rm [a-o,q-t,v-z]*

การทำเช่นนี้จะช่วยให้คุณสามารถกำหนดว่าคุณต้องการสร้างเม็ดละเอียดอย่างไร ดังนั้นหากคุณต้องการลบไฟล์ a และ o คุณสามารถใช้:

rm [a-o,z]*

1

ยังมีอีกเวอร์ชั่นที่ใช้xargs:

ls -1 | grep -v do_not_delete | xargs -I files rm "files"

โปรดทราบว่าxargs -Iจำเป็นต้องจัดการกับชื่อไฟล์รวมถึงช่องว่างอย่างถูกต้อง


1

อีกอย่าง:

for FILE in ./*; do if [[ $FILE != ./u* ]] || [[ $FILE != ./p* ]];then rm $FILE; fi; done;

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

และมันก็เป็นความดีที่ทุบตีอย่างแท้จริง


1

นี่คือตัวแปรอื่น คุณสามารถพิมพ์:

rm -i *

หรือ:

rm --interactive *

ดังนั้นrmจะขอให้คุณยืนยันการลบไฟล์แต่ละไฟล์


1

ใช้:

find . -type f ! -name 'u' ! -name 'p' ! -name '*.ext' -delete
find . -type d ! -name 'u' ! -name 'p' ! -name '*.ext' -delete

เพื่อลบไฟล์ทั้งหมดรวมถึงไดเรกทอรียกเว้นไฟล์ u, p และ. text


0

วิธีง่ายๆที่ทำให้ยุ่งยาก: สมมติว่าคุณต้องการลบทุกอย่างยกเว้น * .pdf:

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