เทศกาลจัดเก็บข้อมูล voicepack ในโครงสร้างไดเรกทอรีตัวอย่างต่อไปนี้:
/usr/share/festival/voices/<language>/<voicepack name>
หนึ่งซับที่ง่ายที่สุด (ควรใช้ls
) ในการพิมพ์เฉพาะ<voicepack name>
ในทุก<language>
ไดเรกทอรีย่อยที่อาจเกิดขึ้นคืออะไร?
เทศกาลจัดเก็บข้อมูล voicepack ในโครงสร้างไดเรกทอรีตัวอย่างต่อไปนี้:
/usr/share/festival/voices/<language>/<voicepack name>
หนึ่งซับที่ง่ายที่สุด (ควรใช้ls
) ในการพิมพ์เฉพาะ<voicepack name>
ในทุก<language>
ไดเรกทอรีย่อยที่อาจเกิดขึ้นคืออะไร?
คำตอบ:
ฉันอยู่ที่ Fedora และชุดเสียงเหล่านี้อยู่ในตำแหน่งที่แตกต่างกันเล็กน้อย:
$ ls /usr/share/festival/lib/voices/*/ -1 | grep -vE "/usr|^$"
kal_diphone
ked_diphone
nitech_us_awb_arctic_hts
nitech_us_bdl_arctic_hts
nitech_us_clb_arctic_hts
nitech_us_jmk_arctic_hts
nitech_us_rms_arctic_hts
nitech_us_slt_arctic_hts
คุณสามารถแก้ไขได้ดังนี้:
$ ls /usr/share/festival/voices/*/ -1 | grep -vE "/usr|^$"
การใช้ls
ในคฤหาสน์นี้มักจะขมวดคิ้วเนื่องจากผลลัพธ์ของls
การแยกวิเคราะห์ยาก ดีกว่าที่จะใช้find
คำสั่งเช่น:
$ find /usr/share/festival/lib/voices -maxdepth 2 -mindepth 2 \
-type d -exec basename {} \;
nitech_us_awb_arctic_hts
nitech_us_bdl_arctic_hts
nitech_us_slt_arctic_hts
nitech_us_jmk_arctic_hts
nitech_us_clb_arctic_hts
nitech_us_rms_arctic_hts
ked_diphone
kal_diphone
คำสั่งนี้ทำงานโดยสร้างรายการพา ธ แบบเต็มไปยังไฟล์ที่มีความลึก 2 ระดับอย่างแท้จริงเมื่อเทียบกับไดเร็กทอรีนี้:
/usr/share/festival/lib/voices
รายการนี้มีลักษณะดังนี้:
$ find /usr/share/festival/lib/voices -maxdepth 2 -mindepth 2
/usr/share/festival/lib/voices/us/nitech_us_awb_arctic_hts
/usr/share/festival/lib/voices/us/nitech_us_bdl_arctic_hts
/usr/share/festival/lib/voices/us/nitech_us_slt_arctic_hts
/usr/share/festival/lib/voices/us/nitech_us_jmk_arctic_hts
/usr/share/festival/lib/voices/us/nitech_us_clb_arctic_hts
/usr/share/festival/lib/voices/us/nitech_us_rms_arctic_hts
/usr/share/festival/lib/voices/english/ked_diphone
/usr/share/festival/lib/voices/english/kal_diphon
แต่เราต้องการส่วนสุดท้ายของไดเรกทอรีเหล่านี้คือโหนดใบไม้ ดังนั้นเราสามารถใช้ประโยชน์ในbasename
การแยกวิเคราะห์:
$ basename /usr/share/festival/lib/voices/us/nitech_us_awb_arctic_hts
nitech_us_awb_arctic_hts
เมื่อรวมทั้งหมดเข้าด้วยกันเราสามารถทำให้find
คำสั่งส่งแต่ละไดเร็กทอรีระดับลึกไปยังbasename
คำสั่ง สัญกรณ์basename {}
คือสิ่งที่กำลังทำการแปลงชื่อฐานเหล่านี้ ค้นหาการโทรผ่าน-exec
สวิตช์
-exec basename {}
คุณช่วยอธิบายที่นี่ได้ไหม
find ~/ -maxdepth 1 -mindepth 1 -type d | xargs du -csh | sort -h
ค้นหาไดเรกทอรีที่ใหญ่ที่สุดเรียงตามขนาด
วิธีที่ง่ายที่สุดคือ
ls -d /usr/share/festival/voices/*/*
ที่ถูกขยายโดยเชลล์ลงในไดเรกทอรีย่อยทั้งหมด/usr/share/festival/voices/
แล้วไปยังเนื้อหาของแต่ละไดเรกทอรีย่อยเหล่านั้น
หากคุณต้องการลงไปสู่ระดับเฉพาะตามที่ชื่อของคุณแนะนำด้วยการใช้งานfind
เช่น GNU และ BSD บางส่วน:
find /usr/share/festival/voices/ -mindepth 2 -maxdepth 3 -type d
ที่จะค้นหาไดเรกทอรีทั้งหมด ( -type d
) ที่อยู่ในไดเรกทอรีย่อย/usr/share/festival/voices/
เนื่องจากmindepth 2
แต่ไม่ลึกกว่า 3 ระดับลง ( maxdepth 3
) จากman find
:
-maxdepth levels
Descend at most levels (a non-negative integer) levels of direc‐
tories below the command line arguments. -maxdepth 0
means only apply the tests and actions to the command line
arguments.
-mindepth levels
Do not apply any tests or actions at levels less than levels (a
non-negative integer). -mindepth 1 means process all files
except the command line arguments.
-type f
เป็น-type d
ควรแก้ไขปัญหานี้ใช่ไหม จะรอการตอบสนองของ slm เกี่ยวกับจุดประสงค์ของ-exec basename {}
-type d
จะพบไดเรกทอรี basename
เป็นความคิดที่ดีมากก็จะพิมพ์เฉพาะชื่อและลบเส้นทาง สมมติว่าคุณต้องการแค่ชื่อนั่นคือสิ่งที่คุณควรทำ ได้ดูและยังman basename
man dirname
ตอบรับทำงานอย่างถูกต้อง แต่อาจจะไม่มีประสิทธิภาพเพราะมัน spawns ใหม่basename
กระบวนการสำหรับแต่ละไดเรกทอรีย่อย:
find /usr/share/festival/lib/voices -maxdepth 2 -mindepth 2 \
-type d -exec basename {} \;
เมื่อเป็นไปได้ควรใช้คุณลักษณะที่มีในตัวfind
เพื่อหลีกเลี่ยงค่าใช้จ่ายของกระบวนการวางไข่ find
มีความสามารถที่กว้างขวางพอสมควรในการปรับเปลี่ยนผลงานพิมพ์โดยใช้-printf
แอ็คชัน การ-print
ดำเนินการเริ่มต้นพิมพ์เส้นทางทั้งหมด แต่ใช้-printf
และสตริงรูปแบบเป็นไปได้ที่จะเลือกส่วนของเส้นทางสำหรับการพิมพ์ เพื่อดึงเพียงส่วนชื่อไฟล์ของเส้นทางที่ไม่มีไดเรกทอรีชั้นนำ (ในขณะที่basename
ไม่) %f
สตริงรูปแบบคือ หากต้องการวางบรรทัดใหม่หลังชื่อไฟล์แต่ละรายการให้รวม\n
ดังนี้:
$ find /usr/share/festival/lib/voices -maxdepth 2 -mindepth 2 \
-type d -printf '%f\n'
nitech_us_awb_arctic_hts
nitech_us_bdl_arctic_hts
nitech_us_slt_arctic_hts
nitech_us_jmk_arctic_hts
nitech_us_clb_arctic_hts
nitech_us_rms_arctic_hts
ked_diphone
kal_diphone
find
ด้วยคำสั่งภายนอกโดยพลการ มันมีประสิทธิภาพน้อยกว่าสำหรับการทำงานที่ติดตั้งไว้find
ภายใน ฉันได้พิจารณาเพิ่มความคิดเห็นในคำตอบของเขา แต่นั่นต้องมีชื่อเสียงมากกว่าที่ฉันมี ไม่จำเป็นต้องเปลี่ยนคำตอบที่คุณยอมรับเนื่องจากคำตอบที่ยอมรับในปัจจุบันนั้นถูกต้องอธิบายได้ดีและใช้เป็นรูปแบบสำหรับกรณีทั่วไปได้มากขึ้น ฉันแค่อยากจะชี้ให้เห็นว่าสำหรับกรณีนี้มีวิธีที่มีประสิทธิภาพมากกว่า
TLDR; สำหรับผู้ที่เพิ่งมาที่นี่ตามชื่อของคำถามนี้ ถึง "แสดงรายการไดเรกทอรีย่อยเฉพาะระดับ n ลึก": ใช้
find -maxdepth N
อยู่ที่ไหนN
หมายเลขใด