仅列出 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 有什么意义。

相关内容