僅列出 n 層深度的子目錄

僅列出 n 層深度的子目錄

Festival 將語音包資料儲存在以下範例目錄結構中:

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

在所有可能眾多的子目錄中,最簡單的一行(最好使用ls)列印出 的是什麼?<voicepack name><language>

答案1

我使用的是 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指令將每個 2 層深度目錄傳遞給basename指令。符號basename {}是進行這些基本名稱轉換的。 Find 透過它的-exec開關來調用它。

答案2

最簡單的是

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

shell 將其擴展到 的所有子目錄/usr/share/festival/voices/,然後擴展到每個子目錄的內容。

如果您只想下降到標題所示的特定級別,並使用findGNU 和 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.

答案3

接受的答案工作正常,但效率有些低,因為它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

答案4

對於使用 bash 的人來說,只需使用 ls 來尋找簡單的東西:

ls -d $PWD/*

建立別名時(在 ~/.bash_aliases 或任何地方),請務必使用單引號:

alias ldf='ls -d $PWD/*'

不引用它將導致 shell 嘗試執行 ls。

雙引號將在建立別名時使用 $PWD 的值建立別名。

如果您願意,您可以使用 $(pwd) ,但是當 bash 為您提供 $PWD 時,我不認為生成子 shell 有什麼意義。

相關內容