Danh sách thư mục con chỉ n cấp sâu


58

Festival lưu trữ dữ liệu voicepack trong cấu trúc thư mục ví dụ sau:

/usr/share/festival/voices/<language>/<voicepack name>

Một lớp lót đơn giản nhất (tốt nhất là sử dụng ls) để in ra chỉ <voicepack name>là, trong tất cả các <language>thư mục con có khả năng là gì?

Câu trả lời:


80

Tôi đang ở trên Fedora và các gói giọng nói này ở một vị trí hơi khác:

$ 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

Bạn chỉ có thể sửa đổi như vậy:

$ ls /usr/share/festival/voices/*/ -1 | grep -vE "/usr|^$"

Sử dụng tìm

Sử dụng lstrong trang viên này thường được tán thành bởi vì đầu ra lskhó phân tích. Tốt hơn để sử dụng findlệnh, như vậy:

$ 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

Chi tiết tìm & tên cơ sở

Lệnh này hoạt động bằng cách tạo danh sách các đường dẫn đầy đủ đến các tệp có độ sâu chính xác 2 cấp đối với thư mục này:

/usr/share/festival/lib/voices

Danh sách này trông như thế này:

$ 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

Nhưng chúng tôi muốn phần cuối của các thư mục này, nút lá. Vì vậy, chúng ta có thể sử dụng basenameđể phân tích nó ra:

$ basename /usr/share/festival/lib/voices/us/nitech_us_awb_arctic_hts
nitech_us_awb_arctic_hts

Đặt tất cả lại với nhau, chúng ta có thể thực hiện findlệnh chuyển từng thư mục sâu 2 cấp cho basenamelệnh. Ký hiệu basename {}là những gì đang thực hiện các chuyển đổi tên cơ sở. Tìm cuộc gọi nó thông qua -execchuyển đổi của nó .


lol, khá nhiều chính xác cùng một câu trả lời, tâm trí tuyệt vời và tất cả những thứ đó :).
terdon

+1 - Đối với những người bị vấp ngã khi tìm hiểu điều gì -exec basename {}, bạn có thể giải thích ở đây không?
dùng66001

@ user66001 - Hãy cho tôi biết nếu điều đó giải thích đủ.
slm

@ user66001 - bạn có thể chấp nhận một trong những câu trả lời nếu nó giải quyết vấn đề của bạn để thỏa mãn 8-)
slm

1
Lệnh find là thứ tôi cần 99% thời gian. Giới hạn cả max và min là key - Tôi chỉ làm max. Ví dụ: find ~/ -maxdepth 1 -mindepth 1 -type d | xargs du -csh | sort -h Tìm các thư mục lớn nhất được sắp xếp theo kích thước
oligofren

23

Đơn giản nhất là

ls -d /usr/share/festival/voices/*/*

Điều đó được mở rộng bởi shell vào tất cả các thư mục con /usr/share/festival/voices/và sau đó đến nội dung của từng thư mục con đó.

Nếu bạn chỉ muốn giảm xuống một mức cụ thể như tiêu đề của bạn gợi ý, với một số triển khai findnhư của GNU và một số BSD:

find /usr/share/festival/voices/ -mindepth 2 -maxdepth 3 -type d

Điều đó sẽ tìm thấy tất cả các thư mục ( -type d) nằm trong thư mục con /usr/share/festival/voices/mindepth 2nhưng không sâu hơn 3 cấp ( maxdepth 3). Từ 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.

Vâng, nó giống như nhìn vào gương 8-)
slm

+1 Làm thế nào cả hai bạn nhận được 2 phiếu là thú vị. Bỏ phiếu chéo giải thích 1 mỗi cái;) PS Tôi muốn tên thư mục, vì vậy chỉ cần thay đổi -type fđể -type dgiải quyết điều này, phải không? Cũng sẽ chờ phản hồi của slm liên quan đến mục đích của-exec basename {}
user66001

@ user66001 có, -type dsẽ tìm thư mục. Đây basenamelà một ý tưởng rất hay, nó sẽ chỉ in tên và xóa đường dẫn. Giả sử bạn chỉ muốn tên, đó là những gì bạn nên làm. Có một cái nhìn man basenamevà cũng có man dirname.
terdon

Cảm ơn terdon - Xin lỗi vì đã không đánh dấu câu trả lời của bạn. Cảm thấy rằng phiên bản hiện tại của SLM 's có thêm thông tin, cho những người cần nó.
dùng66001

1
@ user66001 trước hết, bạn hoàn toàn đúng, slm thực sự tốt hơn. Thứ hai, bạn không bao giờ nên xin lỗi vì đã không chấp nhận, chỉ có thể có một và đó nên là người mà bạn cho là tốt nhất :).
terdon

6

Các câu trả lời được chấp nhận hoạt động chính xác nhưng có phần kém hiệu quả bởi vì nó sinh ra một mới basenametrình cho từng thư mục con:

find /usr/share/festival/lib/voices -maxdepth 2 -mindepth 2 \
    -type d -exec basename {} \;

Khi có thể, tốt hơn là sử dụng các tính năng được tích hợp findđể tránh chi phí cho quá trình sinh sản. findcó một khả năng khá rộng rãi để sửa đổi đầu ra được in bằng -printfhành động. -print Hành động mặc định in toàn bộ đường dẫn, nhưng bằng cách sử dụng -printfvà một chuỗi định dạng, có thể chọn các phần của đường dẫn để in. Để chỉ trích xuất phần tên tệp của đường dẫn mà không có các thư mục hàng đầu (như basename hiện tại), chuỗi định dạng là %f. Để đặt một dòng mới sau mỗi tên tệp, bao gồm \nnhư sau:

$ 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

+1 Cảm ơn câu trả lời của bạn Michael. Tôi cũng có thể thấy được lợi thế của cách thực hiện điều này trong câu trả lời của bạn, nhưng với công việc đưa vào câu trả lời của slm, tôi có hai suy nghĩ về việc chuyển câu trả lời được chấp nhận. Nếu @slm thấy điều này và không có vấn đề gì với việc chọn cái này, tôi sẽ quay lại đây để thay đổi câu trả lời được chấp nhận.
dùng66001

1
Câu trả lời của @ slm được giải thích rõ và bao gồm mô hình sử dụng chung hơn findvới các lệnh bên ngoài tùy ý; nó chỉ kém hiệu quả hơn cho các hoạt động được tích hợp vào find. Tôi đã cân nhắc thêm một bình luận vào câu trả lời của anh ấy, nhưng điều đó đòi hỏi danh tiếng nhiều hơn tôi có. Không cần thay đổi câu trả lời được chấp nhận của bạn, vì câu trả lời hiện được chấp nhận là chính xác, được giải thích rõ ràng và có thể sử dụng làm mẫu cho trường hợp tổng quát hơn; Tôi chỉ muốn chỉ ra rằng đối với trường hợp cụ thể này, có một phương pháp hiệu quả hơn.
Michael Henry

0

TLDR; cho những người chỉ đến đây dựa trên tiêu đề của câu hỏi này; thành "Danh sách thư mục con chỉ n cấp sâu": sử dụng

find -maxdepth N

nơi Nlà bất kỳ số.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.