O Festival armazena dados do pacote de voz na seguinte estrutura de diretórios de exemplo:
/usr/share/festival/voices/<language>/<voicepack name>
Qual é a linha mais simples (de preferência usando ls
) para imprimir apenas os 's, em todos os subdiretórios <voicepack name>
potencialmente numerosos ?<language>
Responder1
Estou no Fedora e esses pacotes de voz estão em um local um pouco diferente:
$ 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
Você pode simplesmente modificar isso assim:
$ ls /usr/share/festival/voices/*/ -1 | grep -vE "/usr|^$"
Usando encontrar
O uso ls
nesta mansão normalmente é desaprovado porque a saída de ls
é difícil de analisar. Melhor usar o find
comando, assim:
$ 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
Detalhes de localização e nome de base
Este comando funciona produzindo uma lista de caminhos completos para arquivos com exatamente 2 níveis de profundidade em relação a este diretório:
/usr/share/festival/lib/voices
Esta lista é assim:
$ 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
Mas queremos a última parte desses diretórios, o nó folha. Portanto, podemos usar basename
para analisá-lo:
$ basename /usr/share/festival/lib/voices/us/nitech_us_awb_arctic_hts
nitech_us_awb_arctic_hts
Juntando tudo, podemos fazer o find
comando passar cada diretório profundo de 2 níveis para o basename
comando. A notação basename {}
é o que está fazendo essas conversões de nome base. Encontre chamadas através do -exec
switch.
Responder2
O mais fácil é
ls -d /usr/share/festival/voices/*/*
Isso é expandido pelo shell para todos os subdiretórios /usr/share/festival/voices/
e depois para o conteúdo de cada um desses subdiretórios.
Se você deseja apenas descer para um nível específico como o título sugere, com algumas implementações find
como GNU e alguns BSD:
find /usr/share/festival/voices/ -mindepth 2 -maxdepth 3 -type d
Isso encontrará todos os diretórios ( -type d
) que estão em um subdiretório por /usr/share/festival/voices/
causa de, mindepth 2
mas não estão mais profundos do que 3 níveis abaixo ( maxdepth 3
). De 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.
Responder3
Oresposta aceitafunciona corretamente, mas é um tanto ineficiente porque gera um novo basename
processo para cada subdiretório:
find /usr/share/festival/lib/voices -maxdepth 2 -mindepth 2 \
-type d -exec basename {} \;
Quando possível, é preferível usar recursos integrados find
para evitar despesas com processos de geração. find
tem uma capacidade bastante extensa de modificar sua saída impressa usando a -printf
ação. A ação padrão -print
imprime o caminho inteiro, mas usando -printf
uma string de formato é possível selecionar partes do caminho para impressão. Para extrair apenas a parte do nome do arquivo do caminho sem os diretórios iniciais (como basename
acontece), a string de formato é %f
. Para colocar uma nova linha após cada nome de arquivo, inclua \n
o seguinte:
$ 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
Responder4
Para alguém que usa o bash e procura algo simples apenas usando ls:
ls -d $PWD/*
Ao criar um alias (em ~/.bash_aliases ou qualquer outro lugar), certifique-se de usar aspas simples:
alias ldf='ls -d $PWD/*'
Não citá-lo resultará no shell tentando executar ls.
Aspas duplas criarão o alias com o valor de $PWD no momento do alias.
Você poderia usar $(pwd) se preferir, mas não vejo sentido em gerar um sub-shell quando o bash fornece $PWD para você.