ไม่รวมไดเร็กทอรีย่อยโดยใช้ find


115

ฉันมีโครงสร้างไดเร็กทอรีแบบนี้

data
|___
   |
   abc
    |____incoming
   def
    |____incoming
    |____processed
   123
    |___incoming
   456
    |___incoming
    |___processed

มีโฟลเดอร์ย่อยที่เข้ามาในทุกโฟลเดอร์ภายในไดเรกทอรีข้อมูล ฉันต้องการรับไฟล์ทั้งหมดจากโฟลเดอร์และโฟลเดอร์ย่อยทั้งหมดยกเว้น def / ขาเข้าและ 456 / dirs ที่เข้ามา ฉันลองใช้คำสั่งต่อไปนี้

 find /home/feeds/data -type d \( -name 'def/incoming' -o -name '456/incoming' -o -name arkona \) -prune -o -name '*.*' -print

แต่มันไม่ทำงานตามที่คาดไว้

ราวี


3
นี้ไม่ได้เป็นคำแนะนำที่ดี แต่ก็จะได้รับคุณออกจากจำนวนมากสถานการณ์ได้อย่างรวดเร็วและสกปรก: ท่อที่grep -v somethingจะไม่รวมสิ่งที่เป็นคุณไม่ต้องการ
Miquel

สิ่งนี้ตอบคำถามของคุณหรือไม่? วิธีการยกเว้นไดเร็กทอรีใน find. command
imz - Ivan Zakharyaschev

คำตอบ:


206

ใช้งานได้:

find /home/feeds/data -type f -not -path "*def/incoming*" -not -path "*456/incoming*"

คำอธิบาย:

  • find /home/feeds/data: เริ่มค้นหาซ้ำจากเส้นทางที่ระบุ
  • -type f: ค้นหาไฟล์เท่านั้น
  • -not -path "*def/incoming*": อย่าใส่อะไรเข้าไปdef/incomingเป็นส่วนหนึ่งของเส้นทาง
  • -not -path "*456/incoming*": อย่าใส่อะไรเข้าไป456/incomingเป็นส่วนหนึ่งของเส้นทาง

ได้รับข้อผิดพลาด "find: bad option-not find: path-list predicate-list"
ราวี

@Ravi คุณใช้ bash shell หรือเปล่า? ฉันเพิ่งทดสอบสิ่งนี้บนเครื่องปลายทางของฉันและมันใช้ได้กับฉัน ลองคัดลอกและวางโซลูชันแทนหากคุณทำการแก้ไขสคริปต์ของคุณ
sampson-chen

มันใช้งานได้ แต่รายชื่อ dirs ไม่ใช่ไฟล์ใน dirs เหล่านั้น
ราวี

1
-pathตรงกับสตริงทั้งหมดดังนั้นหากคุณกำลังทำสตริงfind .ของคุณ-pathจะต้องเป็น./path/to/directory/*
Heath Borders

1
FYI -not -pathจะทำงานในตัวอย่างนี้อย่างแน่นอน แต่findยังคงวนซ้ำในโครงสร้างไดเร็กทอรีและใช้ cpu cycles เพื่อวนซ้ำในไดเร็กทอรี / ไฟล์เหล่านั้นทั้งหมด เพื่อป้องกันไม่ให้findทำซ้ำในไดเรกทอรี / ไฟล์เหล่านั้น (อาจมีไฟล์หลายล้านไฟล์อยู่ที่นั่น) คุณต้องใช้-prune( -pruneตัวเลือกนี้ใช้งานยาก)
เทรเวอร์บอยด์สมิ ธ

9

เพื่อประโยชน์ในการจัดทำเอกสาร: คุณอาจต้องเจาะลึกลงไปอีกเนื่องจากมีกลุ่มดาว search'n'skip จำนวนมาก (เช่นที่ฉันต้องทำ) อาจกลายpruneเป็นว่านั่นคือเพื่อนของคุณในขณะที่-not -pathจะไม่ทำในสิ่งที่คุณคาดหวัง

นี่คือตัวอย่างที่มีค่าของ 15 ตัวอย่างที่ไม่รวมไดเร็กทอรี:

http://www.theunixschool.com/2012/07/find-command-15-examples-to-exclude.html

หากต้องการเชื่อมโยงไปยังคำถามเริ่มต้นการยกเว้นในที่สุดก็ได้ผลสำหรับฉันเช่นนี้:

find . -regex-type posix-extended -regex ".*def/incoming.*|.*456/incoming.*" -prune -o -print 

แล้วถ้าคุณต้องการที่จะหาไฟล์เดียวและยังคงยกเว้น pathes | grep myFile.txtเพียงเพิ่ม

อาจขึ้นอยู่กับเวอร์ชันการค้นหาของคุณด้วย ฉันเห็น:

$ find -version
GNU find version 4.2.27
Features enabled: D_TYPE O_NOFOLLOW(enabled) LEAF_OPTIMISATION SELINUX

5

-nameตรงกับชื่อไฟล์เท่านั้นไม่ใช่เส้นทางทั้งหมด คุณต้องการที่จะใช้แทนสำหรับชิ้นส่วนที่คุณกำลังตัดแต่งกิ่งไดเรกทอรีเช่น-pathdef/incoming


2
find $(INP_PATH} -type f -ls |grep -v "${INP_PATH}/.*/"

7
คำอธิบายบางอย่างอาจทำให้เป็นคำตอบที่ดีกว่ามาก
Cris Luengo

ขอขอบคุณสำหรับข้อมูลโค้ดนี้ซึ่งอาจให้ความช่วยเหลือระยะสั้นที่ จำกัด คำอธิบายที่เหมาะสมจะช่วยเพิ่มมูลค่าในระยะยาวได้อย่างมากโดยแสดงให้เห็นว่าเหตุใดจึงเป็นวิธีแก้ปัญหาที่ดีและจะทำให้มีประโยชน์มากขึ้นสำหรับผู้อ่านในอนาคตที่มีคำถามอื่น ๆ ที่คล้ายคลึงกัน โปรดแก้ไขคำตอบของคุณเพื่อเพิ่มคำอธิบายรวมถึงสมมติฐานที่คุณตั้งไว้
Shawn C.

1
หมายเหตุ: เคล็ดลับนี้ไม่ทำงานหากใช้find ... -print0ร่วมกับต่อมาxargs -0
PHS

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