วิธีการแยกโฟลเดอร์นี้ / ปัจจุบัน / จุดจากค้นหา“ พิมพ์ d”


186
find . -type d

สามารถใช้เพื่อค้นหาไดเรกทอรีทั้งหมดด้านล่างบางจุดเริ่มต้น แต่จะส่งคืนไดเรกทอรีปัจจุบัน ( .) ด้วยซึ่งอาจไม่พึงประสงค์ จะยกเว้นได้อย่างไร

คำตอบ:


194

โซลูชัน POSIX 7 :

find . ! -path . -type d

สำหรับกรณีนี้โดยเฉพาะ ( .) โรงแรมพร้อมสนามกอล์ฟที่ดีกว่าmindepthการแก้ปัญหา (24 VS 26 ตัวอักษร) !แม้ว่าเรื่องนี้อาจจะเป็นเพียงเล็กน้อยยากที่จะพิมพ์เพราะ

หากต้องการยกเว้นไดเรกทอรีอื่น ๆ สิ่งนี้จะใช้ได้น้อยกว่าและต้องการตัวแปรสำหรับความแห้ง:

D="long_name"
find "$D" ! -path "$D" -type d

ต้นไม้ตัดสินใจของฉันระหว่าง!และ-mindepth:

  • สคริปต์? ใช้!สำหรับพกพา
  • เซสชั่นแบบโต้ตอบบน GNU?
    • ยกเว้น.? โยนเหรียญ
    • ยกเว้นlong_name? -mindepthใช้

หากคุณต้องการยกเว้นหลายเส้นทางเพียงทำเช่นfind /path/ ! -path "/path/first" ! -path "/path/second"นี้เป็นวิธีเดียวหรือไม่
Vincent De Smet

2
@VincentDeSmet คุณต้องการยกเว้นเพียงแค่เส้นทางเหล่านั้นหรือไม่หักล้างพวกเขาจริงๆ? หากเพียงแค่เส้นทางคุณสามารถใช้find / ! -regex '/\(a\|b\)/.*'หรือมากกว่าเพียงแค่ท่อผ่าน grep หากต้องการไม่รับเงินคืนข้างต้นจะไม่มีประสิทธิภาพมากและคุณควรใช้-prune: stackoverflow.com/questions/1489277//
Ciro Santilli 郝海东冠状病病六四事件法轮功

ปัญหาของฉันมีดังนี้: ฉันต้องการลบทุกอย่างซ้ำ ๆ ภายในไดเรกทอรียกเว้นไดเรกทอรีย่อย 1 รายการ ฉันใช้findกับgrepเพื่อแยกไดเรกทอรี แต่ไดเรกทอรีหลักยังคงอยู่ทำให้ทุกอย่างถูกลบต่อไป
Vincent De Smet

@VincentDeSmet ฉันไม่เห็นวิธีแก้ปัญหาโดยตรงด้วยfindคุณจะต้องตรวจสอบคำนำหน้า: stackoverflow.com/questions/17959317//แต่ Bash for loop สามารถจัดการได้ :-)
Ciro Santilli ill 冠状病六四事件

คุณอาจต้องการหลบหนีอัศเจรีย์ ( \!) เพื่อให้ปลอดภัย ตัวอย่างทั้งหมดในเครื่องของฉันman findหนีออกมาแล้วดูเหมือนว่ามันอาจเป็น Good Idea ™ แก้ไข - เพิ่งสังเกตว่ามันบอกอย่างชัดเจนว่า:! expr True if expr is false. This character will also usually need protection from interpretation by the shell.
Adrian Günter

201

ไม่เพียง แต่ความลึกของการเรียกซ้ำที่findสามารถควบคุมได้โดย-maxdepthพารามิเตอร์ความลึกยังสามารถ จำกัด จาก“ top” โดยใช้-mindepthพารามิเตอร์ที่เกี่ยวข้อง ดังนั้นสิ่งที่เราต้องการคือ

find . -mindepth 1 -type d

5
ทำงานใน GNU หา แต่น่าเสียดายที่เป็นส่วนขยายของ GNU กับPOSIX 7 พบและแม้แต่ LSB ใช้ POSIX สาธารณูปโภคเปลือก (ไม่ GNU คนขยาย)
โร Santilli郝海东冠状病六四事件法轮功

6
สิ่งนี้ใช้ได้สำหรับฉัน คือ:find . -mindepth 1 -maxdepth 1 -type d ...
racl101

19

ฉันใช้find ./* <...>เมื่อฉันไม่สนใจที่จะละเว้น dotfiles ระดับแรก ( *glob ไม่ตรงกับสิ่งเหล่านี้ตามค่าเริ่มต้นใน bash - ดูตัวเลือก 'dotglob' ใน shopt builtin: https://www.gnu.org/software/bash /manual/html_node/The-Shopt-Builtin.html )

eclipse tmp # find
.
./screen
./screen/.testfile2
./.X11-unix
./.ICE-unix
./tmux-0
./tmux-0/default
eclipse tmp # find ./*
./screen
./screen/.testfile2
./tmux-0
./tmux-0/default

FYI อย่าใช้เคล็ดลับนี้พร้อม-execตัวเลือก ตัวอย่างเช่นถ้าคุณลองfind dir/* -type d -exec rmdir {} \;คุณจะเห็นข้อผิดพลาด
plhn

คุณเข้าใจผิดหรืออาจเข้าใจผิด คำสั่งนั้นจะทำงานได้ดี หากคุณเห็นข้อผิดพลาดพวกเขาจะมาจากrmdirและส่วนใหญ่จะบอกคุณว่าไดเรกทอรีไม่ว่างเพราะfindจะทำการค้นหาในเชิงลึกครั้งแรกในไดเรกทอรีแสดงผู้ปกครองก่อนที่ลูกของพวกเขา
Milos Ivanovic

2
หมายเหตุ: "ไม่สนใจ dotfiles ระดับแรก" ยังหมายถึงการยกเว้นไฟล์ / ไดเรกทอรีที่ซ่อนอยู่ทั้งหมด
โจนาธาน H

2

วิธีแก้ปัญหาง่าย ๆ เช่นกัน (วิธีแก้ปัญหาไม่ทำงานสำหรับฉันบน windows git bash)

find * -type d

มันอาจจะไม่ได้มีประสิทธิภาพมากนัก แต่ทำให้งานสำเร็จและบางครั้งเราก็ต้องการ

[แก้ไข]: ตามที่ @AlexanderMills แสดงความคิดเห็นมันจะไม่แสดงไดเรกทอรีที่ซ่อนอยู่ในตำแหน่งราก (เช่น./.hidden) แต่จะแสดงไดเรกทอรีย่อยที่ซ่อนอยู่ (เช่น./folder/.hiddenSub) [ทดสอบกับทุบตี git บน windows]

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