ค้นหารายการไดเรกทอรีหนึ่งระดับลึกจากไดเรกทอรีที่ตรงกัน


13

ฉันพยายามรับรายการไดเรกทอรีที่อยู่ในโฟลเดอร์เฉพาะ

รับโฟลเดอร์ตัวอย่างเหล่านี้:

foo/bar/test
foo/bar/test/css
foo/bar/wp-content/plugins/XYZ
foo/bar/wp-content/plugins/XYZ/js
foo/bar/wp-content/plugins/XYZ/css
baz/wp-content/plugins/ABC
baz/wp-content/plugins/ABC/inc
baz/wp-content/plugins/ABC/inc/lib
baz/wp-content/plugins/DEF
bat/bar/foo/blog/wp-content/plugins/GHI

ฉันต้องการคำสั่งที่จะกลับมา:

XYZ
ABC
DEF
GHI

โดยพื้นฐานแล้วฉันกำลังมองหาโฟลเดอร์ที่อยู่ใน wp-content / plugins /

การใช้findทำให้ฉันใกล้เคียงที่สุด แต่ฉันไม่สามารถใช้-maxdepthเพราะโฟลเดอร์แตกต่างจากที่ฉันค้นหา

การรันสิ่งต่อไปนี้จะคืนค่าไดเรกทอรีลูกทั้งหมดซ้ำ

find -type d -path *wp-content/plugins/*

foo/bar/wp-content/plugins/XYZ
foo/bar/wp-content/plugins/XYZ/js
foo/bar/wp-content/plugins/XYZ/css
baz/wp-content/plugins/ABC
baz/wp-content/plugins/ABC/inc
baz/wp-content/plugins/ABC/inc/lib
baz/wp-content/plugins/DEF
bat/bar/foo/blog/wp-content/plugins/GHI

คำตอบ:


14

เพียงแค่เพิ่ม-pruneเพื่อให้ไดเรกทอรีที่พบจะไม่ลงมา:

find . -type d -path '*/wp-content/plugins/*' -prune -print

คุณต้องอ้างว่า*wp-content/plugins/*มันเป็นเปลือกกลม

ถ้าคุณต้องการเฉพาะชื่อไดเรกทอรีเมื่อเทียบกับพา ธ เต็มด้วย GNU findคุณสามารถแทนที่-printด้วย-printf '%f\n'หรือสมมติว่าเส้นทางไฟล์ไม่มีอักขระขึ้นบรรทัดใหม่ไปป์เอาท์พุทของคำสั่งข้างต้นไปยังawk -F / '{print $NF}'หรือsed 's|.*/||'(สมมติว่าเส้นทางไฟล์มี อักขระที่ถูกต้องเท่านั้น)

ด้วยzsh:

printf '%s\n' **/wp-content/plugins/*(D/:t)

**/เป็นระดับใดของไดเรกทอรีย่อย (คุณลักษณะที่มีต้นกำเนิดในzshใน nighties ต้นและตอนนี้ที่พบในเปลือกหอยอื่น ๆ ส่วนใหญ่ชอบksh93, tcsh, fish, bash, yashแม้ว่าโดยทั่วไปภายใต้ตัวเลือกบางส่วน) (/)เพื่อเลือกเฉพาะไฟล์ประเภทไดเรกทอรี , Dจะรวมซ่อน (dot) คนที่:tไป รับส่วนท้าย (ชื่อไฟล์)


พบนี้จะแปลงการขึ้นบรรทัดใหม่ใน dirs ?ไป สำหรับทุบตี (ตามแท็กในคำถาม) งานนี้
Isaac

@sorontar findการนำไปใช้งานที่ส่งออก a ?หรืออักขระการแทนที่หรือรูปแบบใด ๆ ของการหลบหนีสำหรับอักขระที่ไม่สามารถพิมพ์ได้จะทำเฉพาะเมื่อเอาต์พุตไปยังเทอร์มินัลไม่ใช่เมื่อไปที่ไพพ์เช่นที่นี่
Stéphane Chazelas

คำสั่งแรก (และไม่ใช่ zsh เท่านั้น) ที่อยู่ในคำตอบของคุณไม่มีไพพ์มันเป็นคำสั่งที่ฉันทดสอบและเป็นคำสั่งที่เปลี่ยนบรรทัดใหม่ เมื่อถูกไพพ์ตามที่คุณได้กล่าวไว้: "สมมติว่าพา ธ ไฟล์ไม่มีอักขระขึ้นบรรทัดใหม่" ดังนั้นคุณยอมรับแล้วว่ามันล้มเหลวด้วยการขึ้นบรรทัดใหม่
Isaac

@ Sorontar ขอโทษฉันคิดว่าคุณกำลังแสดงความคิดเห็นในส่วนที่สองที่จะบอกว่ามันจะทำงานได้ดีขึ้นเพราะบรรทัดใหม่จะหนีดังนั้นจะไม่ทำลายสมมติฐานที่เราทำsed/ awkไฟล์ทั้งหมดอยู่ในบรรทัด ตอนนี้บางคนอาจเถียงว่าได้รับABC?BCDหรือABC\nBCDสำหรับการส่งออกโต้ตอบ / ขั้วจะเป็นประโยชน์มากกว่าได้รับสองABCและเส้นผบที่เรียกว่าBCD $'ABC\nBCDที่ระดับการนำเสนอของผู้ใช้เราสามารถชี้ให้เห็นว่าสำหรับไฟล์ที่เรียกว่า$'AB\bC'เมื่อเอาต์พุตไปยังเทอร์มินัลคุณจะเห็นACโดยไม่มีการ?แทนที่ ...
Stéphane Chazelas

ค้นหาด้วย -prune และการใช้ printf เพื่อแก้ไขรูปแบบผลลัพธ์ให้ฉันอย่างที่ฉันขอ ที่สมบูรณ์แบบ - ขอบคุณ!
Nick

4

ทุบตี ically:

shopt -s globstar
printf "%s\n" **/wp-content/plugins/*

พิมพ์:

bat/bar/foo/blog/wp-content/plugins/GHI
baz/wp-content/plugins/ABC
baz/wp-content/plugins/DEF
foo/bar/wp-content/plugins/XYZ

หรือ

shopt -s globstar
for d in **/wp-content/plugins/*; do printf "%s\n" ${d##*/}; done

พิมพ์:

GHI
ABC
DEF
XYZ

ไม่ว่าจะพิมพ์ไฟล์ภายใน dirs เช่นกัน โปรดอ่านคำตอบของฉัน
ไอแซค

จุดดี; ขอขอบคุณ! ฉันสร้างโครงสร้างไดเรกทอรีใหม่ แต่ไม่ได้วางไฟล์ทดสอบไว้ในนั้น
Jeff Schaller

4

คุณสามารถรับเงินคืนได้findเรียงลำดับจาก:

find / -type d -path *wp-content/plugins -exec find {} -maxdepth 1 -mindepth 1 -type d \;

3

สำหรับ Bash: Simple (ใช้ได้กับไฟล์ / dirs ที่มีช่องว่างและบรรทัดใหม่ ):

shopt -s globstar                    # allow ** for several dirs.
a=(**/wp-content/plugins/*/)         # capture only wanted dirs.
a=("${a[@]%/}")                      # remove trailing slash (dirs) `/`.
printf '%s\n' "${a[@]##*/}"          # print only the last dir name.

จะพิมพ์:

GHI
ABC
DEF
XYZ

แม้ว่าจะมีไฟล์ที่สร้างขึ้น


โปรดทราบว่ามันไม่ได้ดู dirs ซ่อนอยู่ภายในข้ามไฟล์ที่ซ่อนอยู่ (ดูdotglobตัวเลือกหากที่ไม่พึงประสงค์) และรวมถึง symlinks ไปยังไดเรกทอรีนอกเหนือไปจากไดเรกทอรี ( **จะ symlinks ยังขวางในทุบตี 4.2 และก่อนหน้า)
Stéphane Chazelas

@ StéphaneChazelasไฟล์ที่ซ่อนอยู่? คำถามที่ถามไม่มีใคร dirs เท่านั้น ได้คุณสามารถเลือกไดเรซที่ซ่อนอยู่ได้อย่างอิสระ (เป็นคุณลักษณะหากต้องการ) และใช่ symlink ไม่ได้เป็นแบบขวางในเวอร์ชันปัจจุบันของ bash
Isaac

1
โปรดอย่าถือว่าความคิดเห็นของฉันเป็นการรุกราน ฉันยกระดับคำตอบของคุณและเพิ่มบันทึกย่อไว้ข้างล่างเพื่อระบุข้อเท็จจริงบางประการเกี่ยวกับเรื่องนี้ซึ่งไม่จำเป็นต้องชัดเจน findไม่ได้ยกเว้นไฟล์ใด ๆ globs ไม่รวมไฟล์ dot มันควรค่าแก่การชี้ให้เห็นว่าเป็นความแตกต่างระหว่างทั้งสอง
Stéphane Chazelas

3

treeคำสั่งได้รับการออกแบบว่าเพื่อวัตถุประสงค์นี้ ความลึกสามารถควบคุมได้ด้วยการ-Lตั้งค่าสถานะ นี่คือตัวอย่างในเว็บไซต์ Wordpress ท้องถิ่นที่ฉันดูแล:

$ tree -L 1 wp-content/
wp-content/
├── index.php
├── plugins
└── themes

2 directories, 1 file

$ tree -L 2 wp-content/
wp-content/
├── index.php
├── plugins
   ├── akismet
   ├── contact-form-7
   ├── index.php
   └── wordpress-seo
└── themes
    ├── index.php
    ├── twentyfifteen
    └── twentysixteen

11 directories, 3 files

$ tree -L 1 wp-content/plugins/
wp-content/plugins/
├── akismet
├── contact-form-7
├── index.php
└── wordpress-seo

5 directories, 1 file

1

สร้างคำตอบของ DopeGhoti วิธีการจับคู่แบบวนซ้ำ:

find / -type d -iregex '.*/wp-content/plugins' -print0 | while read -r -d $'\0' D; do
    find "$D" -maxdepth 2 -mindepth 1
done

เหตุผลในการทำเช่นนี้คือคุณอาจพบว่ามันสับสน / ยุ่งยากกับหลาย ๆ ตัว-execในขณะที่ยังคงหลีกเลี่ยงปัญหาเกี่ยวกับชื่อไฟล์แปลก ๆ ที่มี \ n '' ฯลฯ -print0 จะใช้ตัวคั่น null ระหว่างผลลัพธ์


0

สร้างสิ่งที่คุณเริ่มต้น:

find -type d -path *wp-content/plugins/* | egrep -o "wp-content/plugins/[^/]+($|/)" | sed -r "s~wp-content/plugins/([^/]+)($|/)~\1~" | uniq  

egrep grabs * wp-content / plugins / * และอักขระใด ๆ จนถึงเครื่องหมายทับ / หรือท้ายบรรทัด $ ถัดไป - ซึ่งรวมถึงส่วนที่คุณต้องการ

sedด้วย ~ ตัวคั่นเลือกส่วนที่คุณต้องการใช้วงเล็บชุดแรก () และใช้ \ 1 (สิ่งที่คุณต้องการ) เพื่อทดแทนทุกอย่าง

uniqกรองผลลัพธ์ที่ซ้ำกัน

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