ใน linux วิธีการลบไฟล์ทั้งหมดยกเว้นรูปแบบ * .txt


73

ฉันรู้วิธีการลบไฟล์ภายใต้ไดเรกทอรีปัจจุบันโดยtxt rm *.txtไม่มีใครรู้วิธีการลบไฟล์ทั้งหมดในไฟล์ยกเว้นไดเรกทอรีปัจจุบันtxt?


20
และเช่นเคยทดสอบคำตอบให้กับคำสั่งที่ไม่เป็นอันตรายเหมือนจริงก่อนที่จะพยายามที่จะเรียกls rm
chepner

คำตอบ:


111

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

find . -type f ! -name '*.txt' -delete

หรือคุณสมบัติที่ทำให้กลมโตของทุบตี:

shopt -s extglob
rm *.!(txt)

หรือเป็น zsh:

setopt extendedglob
rm *~*.txt(.)
#  ||     ^^^ Only plain files
#  ||^^^^^ files ending in ".txt"
#  | \Except
#   \Everything

สิ่งเหล่านี้บางอย่างอาจต้องมีการปรับขึ้นอยู่กับว่าคุณมีโฟลเดอร์และสิ่งที่คุณต้องการจะทำกับพวกเขา
Kevin

1
ไม่ควร*.!(txt)จะเป็น!(*.txt)?
Lri

@LauriRanta ขึ้นอยู่กับสิ่งที่อยู่ในโฟลเดอร์ซึ่งเราไม่ได้รับคำตอบ ไม่เป็นไรถ้าไฟล์ทั้งหมดมีนามสกุลและrmจะสำลักถ้ามีโฟลเดอร์
Kevin

ฉันมีปัญหากับตัวยึด เมื่อฉันใช้สไตล์กลมในสคริปต์ทุบตีมันบ่นเกี่ยวกับข้อผิดพลาดทางไวยากรณ์และวงเล็บ อย่างไรก็ตามการทำมันจาก CLI ทำงาน
CMCDragonkai

1
@izogfif ตรวจสอบว่าสิ่งนี้find . -type f ! -name "*.txt" | xargs -r rmจะทำงานใน GNU \ xargs คำสั่ง BSD และ UNIX xargs อาจไม่มี -r คุณต้องตรวจสอบภายในเครื่องของคุณman xargs
Ntwobike

10

หากคุณต้องการลบไฟล์ทั้งหมดยกเว้น '* .txt' คุณสามารถใช้คำสั่งต่อไปนี้:

$ find . -type f ! -name "*.txt" -exec rm -rf {} \;

แต่ถ้าคุณต้องการลบไดเรกทอรีพร้อมกับไฟล์คุณสามารถใช้สิ่งนี้:

$ find . ! -name "*.txt" -exec rm -r {} \;


9

มีหลายวิธีที่สามารถทำได้ แต่วิธีที่ง่ายที่สุดคือ (ทุบตี):

shopt -s extglob
rm !(*.txt)

4

ทางออกหนึ่งที่ไม่มีfind:

mv dir/*.txt otherdir/
rm -r dir
mv otherdir dir

สิ่งนี้น่าจะใช้ได้กับเชลล์ทุกชนิด


3

คุณสามารถใช้ grep และ xargs แบบกลับด้านได้

ls | grep -v .txt$| xargs rm

ls | grep -v *.txt | xargs rmทำงานได้ดีเช่นกัน
phillipsk

@phillipsk grep -v *.txtจะทำงานเฉพาะในกรณีที่มี.txtไฟล์เดียว หากไม่มีgrepจะใช้*.txtเป็นลวดลาย ถ้ามีมากกว่าหนึ่งก็จะค้นหาชื่อไฟล์แรกภายในทั้งหมดของอื่น ๆไฟล์ไม่สนใจเอาท์พุทจาก.txt ls(ผลลัพธ์ที่แน่นอนอาจขึ้นอยู่กับตัวเลือก glob ของเชลล์)
JigglyNaga

.txt$จะจับคู่สตริงที่ลงท้ายด้วยtxtโดยไม่คำนึงถึงจุด เพราะgrepรับนิพจน์ปกติเป็นพารามิเตอร์ ดังนั้นไฟล์a.txtและaatxtและa-txtทั้งหมดจะถูกจับคู่โดยนิพจน์นี้ ls | grep -v \\.txt$ | xargs --no-run-if-empty rmการแสดงออกที่ถูกต้องควรจะเป็น สำหรับคนที่อยากรู้อยากเห็น: ถ้าคุณต้องการเล่นกับนิพจน์อย่างปลอดภัยให้ใช้นิพจน์ทดสอบนี้ls | grep \\.txt$ | xargs --no-run-if-empty echo(หมายเหตุ: ไม่มีการ-vตั้งค่าสถานะและrm=>echo) Note2: คุณอาจสังเกตเห็นแบ็กสแลชสองครั้ง หนึ่งคือสำหรับ regex อีกอันสำหรับทุบตีเพื่อหนีเฉือน
Dimitry K

1

เพียงทำ:

rm $(ls -I "*.txt" ) #Deletes ประเภทไฟล์ยกเว้น * .txt

ในทำนองเดียวกันหากจำเป็นต้องลบ "ยกเว้นหนึ่งประเภทไฟล์" ให้ทำ:

rm $(ls -I "*.txt" -I "*.pdf" ) #Deletes ประเภทไฟล์ยกเว้น * .txt & * .pdf


ยินดีต้อนรับสู่ StackExchange! -Iตัวเลือกที่อาจจะมีประโยชน์ แต่เห็นทำไมไม่แยกคำสั่ง ls และ| xargsบรรลุผลอะไร หากไม่มีข้อโต้แย้งใด ๆ มันจะทำงานechoกับอินพุตทั้งหมด
JigglyNaga

สิ่งที่xargsควรจะบรรลุ
dhag

ขอบคุณ xargs ไม่มีประโยชน์ในกรณีข้างต้นได้ถูกแก้ไขแล้ว
Surya

0

วิธีนี้ใช้สำหรับลบไฟล์และโฟลเดอร์ที่ซ่อนอยู่ (จุด)ทั้งหมดยกเว้นไฟล์ที่ระบุ ( .mydir):

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