Tengo el mismo problema que me preguntaron Cambiar el nombre de los archivos de música a los que les faltan extensiones de archivo y el guión proporcionado por @Gilles me pareció muy educativo, pero desafortunadamente no funcionó como esperaba. Lo que estaba buscando era un script que agregara una extensión de archivo a todos los archivos de música sin extensión en todos los subdirectorios, en todos los niveles, debajo de "/ruta/a/música/directorio/". El parámetro de línea de comando sugerido
/path/to/music/directory/{**/,}*
hace que el script revise todos los archivos en los subdirectorios un nivel por debajo de "/ruta/a/música/directorio/" pero no en niveles inferiores a ese. ¿Qué parámetro de línea de comando debo usar para recorrer todos los archivos en todos los niveles debajo de "directorio/"?
También agradecería una indicación de la documentación para el
{**/,}*
parte.
Por cierto, para aquellos interesados en la respuesta original. Descubrí que el script funciona mejor después de cambiar la línea.
file -i "$@" |
a
file --mime-type "$@" |
(Si hubiera tenido el nivel de privilegio, habría puesto esto como comentario en la respuesta original)
Respuesta1
Creo que solo tienes que activar la globstar
opción bash, porque no está activa por defecto enubuntu, como se explica a continuación.
La expresión /path/to/music/directory/{**/,}*
contiene dos construcciones de expansión: tiene una expansión de llave y luego una expansión de nombre de ruta.
Expansión de llaves
La expansión de llaves se explica mejor con un ejemplo:
$ printf '%s\n' before-{a,bb,1,22}-after
before-a-after
before-bb-after
before-1-after
before-22-after
(He usado, aquí y en lo siguiente, el comando printf '%s\n' item1 item2 etc..
similar echo
pero imprime cada elemento en una nueva línea)
Verá que cada elemento separado por comas entre llaves da como resultado un elemento expandido.
El ejemplo original, que contiene entre llaves los elementos **/
y un elemento vacío, se expande a
$ printf '%s\n' /path/to/music/directory/{**/,}*
/path/to/music/directory/**/*
/path/to/music/directory/*
estrella global
Pasemos ahora al bash glob **
, que se menciona dos veces en elpágina del manual de bash, tanto en relación con la opción de shell globstar
, y el significado es el siguiente:
el patrón ** utilizado en un contexto de expansión de nombre de ruta coincidirá con archivos y cero o más directorios y subdirectorios.
Esta opción de shell no esactivopor defecto en Ubuntu:
$ shopt globstar
globstar off
Puedes activarlo con
shopt -s globstar
(use shopt -u globstar
para desactivarlo).
Si tenemos la siguiente estructura de directorios:
$ find first/ | sort
first/
first/aaa
first/second
first/second/bbb01
first/second/bbb02
first/second/third
first/second/third/ccc1
first/second/third/ccc2
first/second/third/ccc3
podríamos tener las siguientes expansiones:
$ printf '%s\n' first/**/a*
first/aaa
$ printf '%s\n' first/**/b*
first/second/bbb01
first/second/bbb02
$ printf '%s\n' first/**/c*
first/second/third/ccc1
first/second/third/ccc2
first/second/third/ccc3
para que pueda ver que **
se puede expandir a más de un elemento de nombre de ruta.
Respuesta2
yo haría algo como esto
#! /bin/bash
[[ -d "$1" ]] || { echo "$1 not a directory, exiting..."; exit 1; }
find "$1" -type f | while read F; do
# do what you want with the "$F"
done
exit 0
y luego invocar el script a través de./my_script <directory>