rm -rf ไฟล์ทั้งหมดและไฟล์ที่ซ่อนอยู่ทั้งหมดโดยไม่ต้อง & .. ข้อผิดพลาด


82

rm -rf /some/path/* ลบไฟล์ที่ไม่ถูกซ่อนทั้งหมดใน dir (และส่วนย่อย)

rm -rf /some/path/.* ลบไฟล์ที่ซ่อนอยู่ทั้งหมดใน dir นั้น (แต่ไม่ใช่ subdirs) และยังให้ข้อผิดพลาด / คำเตือนต่อไปนี้:

rm: cannot remove directory: `/some/dir/.'
rm: cannot remove directory: `/some/dir/..'

เป็นวิธีที่เหมาะสมในการลบไฟล์และโฟลเดอร์ที่ซ่อนอยู่และไม่ได้ซ่อนอยู่ในไดเรกทอรีเป้าหมายซ้ำโดยไม่ได้รับคำเตือน / ข้อผิดพลาดเกี่ยวกับ.และ..คืออะไร?

คำตอบ:


39

คุณสามารถส่งข้อความข้อผิดพลาดไปยัง /dev/null

rm -rf /some/path/.* 2> /dev/null

คุณสามารถทำได้เพียงแค่

rm -rf /some/path/
mkdir /some/path/

... จากนั้นคุณไม่ต้องกังวลกับไฟล์ที่ซ่อนอยู่ตั้งแต่แรก


2
แต่ถ้าฉันต้องการลบไฟล์ที่ซ่อนเท่านั้น
CMCDragonkai

@CMCDragonkai ที่ควรจะเป็นคำถามที่แตกต่างกัน แต่คุณสามารถหาคำตอบในคำตอบของ Gilles ( rm ..?* .[!.]*ควรทำ)
evilsoup

15
การไม่ลบและสร้างไดเรกทอรีใหม่มีความเสี่ยงที่การอนุญาตของไฟล์จะไม่ถูกต้องในภายหลัง (โดยเฉพาะอย่างยิ่งที่สำคัญในสภาพแวดล้อมของเซิร์ฟเวอร์) ใครบ้างที่สามารถสร้างโฟลเดอร์ที่มีสิทธิ์เหมือนเดิมโดยอัตโนมัติ
Yo Ludke

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

การลบไดเรกทอรีนั้นไม่สามารถทำได้ ในกรณีของฉันไดเร็กตอรี่เป็นไดรฟ์ข้อมูลระดับเสียง, และในขณะที่ฉันสามารถทำสิ่งที่ฉันต้องการภายในไดรฟ์ข้อมูล, ฉันไม่สามารถเปลี่ยนระดับเสียงจากภายในคอนเทนเนอร์
dovidweisz

85

*ตรงจุดไฟล์ที่ไม่ใช่ทั้งหมด.[!.]*ตรงกับไฟล์ทั้งหมดยกเว้นจุด.และไฟล์ที่มีชื่อขึ้นต้นด้วย..และ..?*ตรงกับไฟล์ dot ..dot-ทั้งหมดยกเว้น พวกเขาช่วยกันให้ตรงกับไฟล์อื่น ๆ กว่าและ. ..หากรูปแบบใดรูปแบบหนึ่งในสามรูปแบบนั้นตรงกับสิ่งใดเลยมันก็จะขยายออกไปเอง rm -fไม่สนใจข้อโต้แย้งที่ไม่มีอยู่ดังนั้นสิ่งนี้จึงไม่สำคัญ

rm -rf ..?* .[!.]* *

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

find . -name . -o -prune -exec rm -rf -- {} +

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


8
นี่ควรเป็นคำตอบที่ได้รับการยอมรับเนื่องจากป้องกันไม่ให้ผู้ปกครองข้ามเส้นทางและการลบที่เป็นไปได้
rbellamy

findทางเลือกผลตอบแทน "ความสำเร็จ" แม้ว่าบางไฟล์ไม่ถูกลบเรียบร้อยแล้ว ไม่ดีสำหรับสคริปต์
Franklin Yu

สำหรับfindคำสั่งที่สองของคุณmanpage ของ find states "เนื่องจาก -delete บอกถึง -depth คุณไม่สามารถใช้ -prune และ -delete ร่วมกันได้อย่างเป็นประโยชน์" - คุณยังใช้-prune -delete?
Doktor J

@DoktorJ แน่นอน-pruneไม่ได้ทำอะไรที่นี่ และเมื่ออ่านกลับมาฉันเห็นว่าฉันไม่ได้ตอบคำถามอย่างถูกต้อง: ฉันดูแลไม่ให้เงินคืน แต่คำถามนั้นขอให้ลบแบบเรียกซ้ำ ฉันแก้ไขคำตอบของฉันแล้ว
Gilles

2
@haylem ใน zsh คุณต้องเขียน.[^.]*แทน.[!.]*เมื่อเปิดใช้งานการแทนที่ประวัติ (โดยค่าเริ่มต้นคือกรณีที่โต้ตอบ แต่ไม่ใช่ในสคริปต์) เนื่องจาก zsh วิเคราะห์!คำเป็นการอ้างอิงประวัติ แต่ใน zsh คุณไม่จำเป็นต้องทำเช่นนั้นในตอนแรกคุณสามารถใช้*(D)เพื่อรวมไฟล์ dot (ที่ไม่มี.หรือ..) ในการจับคู่สัญลักษณ์แทน
Gilles

21

เพิ่งรู้ว่านี่เป็นวิธีที่สะดวกที่สุดใน Linux distros ส่วนใหญ่:

ls -A1 | xargs rm -rf

ที่ไหน

-A= ทำรายการทุกอย่างยกเว้น .และ..

-1 = ใส่ทุกรายการในหนึ่งบรรทัด


4
ข้อเสียที่ฉันเห็นคือ: คุณต้อง 'cd' ลงในไดเรกทอรีเพื่อทำสิ่งนี้
Kumar

ls -A1 /your/path/ | xargs rm -rfควรสมัคร
godzillante

nope..it ไม่ช่วย - ตัวอย่างเช่น: ls -A1 ~ / test / | xargs rm -rf คำสั่งนี้จะลบไฟล์ซึ่งขณะนี้ฉัน 'ซีดีเป็น' .. ไม่ได้อยู่ในไดเรกทอรี ~ / test
Kumar

5
มันไม่ทำงานหากชื่อไฟล์ใด ๆ มีช่องว่างขึ้นบรรทัดใหม่อัญประกาศหรือแบ็กสแลช
Stéphane Chazelas

1
-1 เนื่องจากความคิดเห็นด้านบน ↑↑↑↑↑↑↑↑
บางสิ่งบางอย่าง

15

ทั้งการเปลี่ยนแปลงdotglobตัวเลือกของเปลือกและการใช้งานหรือใช้สิ่งที่ต้องการ*find

find somedir -mindepth 1 -delete

2
หรือคุณสามารถrm -rf /some/dirสร้างไดเรกทอรีที่ว่างเปล่าขึ้นมาใหม่ได้
tripleee

ตัวเลือกที่ดีที่สุดจนถึง ปลอดภัยมากเนื่องจากคุณระบุเส้นทางไดเรกทอรีอย่างชัดเจน
Yanick Girouard

4

สิ่งนี้น่าจะทำงานได้เหมือนคำตอบ @Gilles แต่กะทัดรัดกว่า:

rm -rf {,.[!.],..?}*

หรือ

rm -rf dir/to/files/{,.[!.],..?}*

ควรเพิ่มการifใช้งานในสคริปต์เพื่อความปลอดภัย:

if [ -d "$DIR" ]; then
    rm -rf ${DIR}/{,.[!.],..?}*
fi

1
ผิดปกติพอเป็นนามแฝงทุบตีใน Ubuntu 16.04 LTS คำตอบก่อนหน้านี้ไม่ทำงาน อย่างไรก็ตามalias cleandir='rm -rf {,.[!.],..?}*'ไม่
Steven Ventimiglia

3

ค้นหาคือเพื่อนของคุณ

find ! -name '.' ! -name '..' -delete

% find ! -name '.' ! -name '..'
./test
./test4
./test4/.test6
./test3
./.test5
./test2
% find ! -name '.' ! -name '..' -delete    
% find ! -name '.' ! -name '..'     
%             

หากคุณต้องการใช้การค้นหาแบบอื่น ๆ ซ้ำ ๆ ไดเรกทอรีปัจจุบันของคุณ ($ PWD) ให้เพิ่มเส้นทางทันทีหลังfindคำสั่ง เช่นfind /path ! -name '.' ! -name '..' -delete. หากคุณต้องการลดnจำนวนไดเรกทอรีให้ใช้-maxdepth nตัวเลือกหลังจาก/pathพารามิเตอร์

คำสั่งดังกล่าวได้รับการทดสอบบนระบบ Ubuntu 13.04 มีแนวโน้มที่จะทำงานกับระบบลินุกซ์อื่น ๆ ที่ทันสมัย


เพื่อลบไดเรกทอรีทั้งหมดในไดเรกทอรีปัจจุบันที่คุณสามารถทำได้find . ! -name '.' ! -name '..' -type d -delete
Andy

2

เป็นวิธีที่เหมาะสมในการลบไฟล์และโฟลเดอร์ที่ซ่อนอยู่และไม่ได้ซ่อนอยู่ในไดเรกทอรีเป้าหมายซ้ำโดยไม่ได้รับคำเตือน / ข้อผิดพลาดเกี่ยวกับอะไร และ ..

สมมติว่าไดเรกทอรีที่เป็นปัญหา./dirนั้น

rm -rf ./dir

จะลบไฟล์ทั้งหมดใน./dirรวมถึงไฟล์และไดเรกทอรีที่ซ่อนอยู่ซ้ำและรวมถึง./dirไดเรกทอรีเอง

หากคุณไม่ต้องการลบไดเรกทอรีเองคุณอาจสร้างมันขึ้นมาใหม่ในภายหลังหรือใช้

find ./dir -mindepth 1 -delete

หรือถ้าคุณfindไม่สนับสนุน-delete,

find ./dir -mindepth 1 -depth -exec rm -rf {} ';'

การใช้-mindepth 1ช่วยให้คุณสามารถเก็บไดเรกทอรีระดับบนสุด./dirได้


ควรทำเครื่องหมายเป็นคำตอบที่ดีที่สุด
kitingChris

1

ฉันขอแนะนำให้คุณทดสอบด้วย

จุด Turn- ON (ไฟล์ที่ซ่อนอยู่)

  • ชุด dotglob

    shopt -s dotglob

จุดปิด - เปิด

  • ไม่มีการตั้งค่า dotglob

    shopt -u dotglob

วิธีนี้ใช้ได้ผลเหมือนที่ฉันต้องการสำหรับคำสั่งcopyที่ไม่มีไดเรกทอรีที่ซ่อนอยู่

    shopt -s    dotglob
    cp    -rvn  ./$from/*  ./$too/
    shopt -u    dotglob

ดังนั้นฉันจึงลบ (ลบ) และอุ๊ปส์ ...

    shopt -s    dotglob
    rm -fr ../message_splitter--044a/*
    shopt -u    dotglob

... นั่นก็ใช้ได้เช่นกัน!

มันเกิดขึ้นกับฉันที่คุณรักผู้อ่านไม่สามารถมองเห็นmessage_splitterไดเรกทอรี วิธีใดก็ตามที่มี.svnโฟลเดอร์ที่ต้องการลบและคัดลอกลงใน

จากmanหน้า ...

dotglob หากตั้งค่า bash จะมีชื่อไฟล์ที่ขึ้นต้นด้วย `. ' ในผลลัพธ์ของการขยายชื่อพา ธ

อ้างอิง:


-2

ลองรหัสนี้:

Dirlist=``find /some/path/ -type d -name '.[^.]*'`
for HiddenDir in $Dirlist
do
    rm -rf $HiddenDir
done
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.