Festival almacena los datos del paquete de voz en la siguiente estructura de directorio de ejemplo:
/usr/share/festival/voices/<language>/<voicepack name>
¿Cuál es el resumen más simple (preferiblemente usando ls
) para imprimir solo los 's, en todos los subdirectorios <voicepack name>
potencialmente numerosos ?<language>
Respuesta1
Estoy en Fedora y estos paquetes de voz están en una ubicación ligeramente 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
Puedes modificar esto así:
$ ls /usr/share/festival/voices/*/ -1 | grep -vE "/usr|^$"
Usando buscar
El uso ls
en esta mansión suele estar mal visto porque el resultado ls
es difícil de analizar. Es mejor usar el find
comando, así:
$ 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
Detalles de búsqueda y nombre base
Este comando funciona generando una lista de rutas completas a archivos que tienen exactamente 2 niveles de profundidad con respecto a este directorio:
/usr/share/festival/lib/voices
Esta lista se ve así:
$ 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
Pero queremos la última parte de estos directorios, el nodo hoja. Entonces podemos utilizar basename
para analizarlo:
$ basename /usr/share/festival/lib/voices/us/nitech_us_awb_arctic_hts
nitech_us_awb_arctic_hts
Poniéndolo todo junto, podemos hacer que el find
comando pase cada directorio de 2 niveles de profundidad al basename
comando. La notación basename {}
es lo que realiza estas conversiones de nombres base. Find lo llama a través de su -exec
interruptor.
Respuesta2
Lo más fácil es
ls -d /usr/share/festival/voices/*/*
El shell lo expande a todos los subdirectorios /usr/share/festival/voices/
y luego al contenido de cada uno de esos subdirectorios.
Si solo desea descender a un nivel específico como sugiere el título, con algunas implementaciones de find
GNU y algunas BSD:
find /usr/share/festival/voices/ -mindepth 2 -maxdepth 3 -type d
Eso encontrará todos los directorios ( -type d
) que están en un subdirectorio de /usr/share/festival/voices/
debido a mindepth 2
pero que no están a más de 3 niveles hacia abajo ( 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.
Respuesta3
Elrespuesta aceptadafunciona correctamente pero es algo ineficiente porque genera un nuevo basename
proceso para cada subdirectorio:
find /usr/share/festival/lib/voices -maxdepth 2 -mindepth 2 \
-type d -exec basename {} \;
Cuando sea posible, es preferible utilizar funciones integradas find
para evitar el gasto de los procesos de generación. find
tiene una capacidad bastante amplia para modificar su salida impresa utilizando la -printf
acción. La -print
acción predeterminada imprime la ruta completa, pero usando -printf
una cadena de formato es posible seleccionar partes de la ruta para imprimir. Para extraer solo la parte del nombre de archivo de la ruta sin los directorios principales (como basename
lo hace), la cadena de formato es %f
. Para colocar una nueva línea después de cada nombre de archivo, incluya \n
lo siguiente:
$ 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
Respuesta4
Para alguien que usa bash y busca algo simple simplemente usando ls:
ls -d $PWD/*
Al crear un alias (en ~/.bash_aliases o donde sea), asegúrese de usar comillas simples:
alias ldf='ls -d $PWD/*'
Si no lo cita, el shell intentará ejecutar ls.
Entre comillas dobles se creará el alias con el valor de $PWD en el momento del alias.
Podrías usar $(pwd) si lo prefieres, pero no veo el sentido de generar un sub-shell cuando bash te proporciona $PWD.