Recientemente convertí todos mis archivos FLAC a una velocidad de muestreo más baja de 44.1 kHz y una profundidad de bits de 24 bits (porque iPhone / iPod no admite nada por encima de eso) usando XLD en mi Mac OS 10.7 (Lion).
Aunque le dije a XLD que sobrescribiera todos los archivos anteriores, XLD agregó un (1)
al final del mismo archivo como de
some_song.m4a
a
some_song(1).m4a
Así que ahora quiero eliminar eso (1)
de todos los archivos FLAC que convertí.
Sé que probablemente podría haber usado algún programa o incluso un AppleScript para cambiar el nombre de los archivos, pero quería aprender a usar la línea de comando de la vieja escuela.
Sé que find . -name *\(1\).m4a
tomará todo el archivo FLAC convertido.
A continuación, sé que tengo que hacer algo -exec
y mv
cambiar el nombre de todos los archivos encontrados. Pero lo que no puedo entender es cómo mantener el nombre de archivo original y solo eliminar el (1)
.
¿Tal vez necesito hacer una captura de expresiones regulares grupales para almacenar la parte del nombre de archivo que no quiero modificar? O tal vez no sea posible hacer todo en una línea y debería crear un script de shell (que no me siento tan cómodo haciendo, pero estoy dispuesto a intentarlo).
¡Cualquier sugerencia o sugerencia es bienvenida! ¡Gracias!
find
) pero que puede estar resolviendo su problema real (convertir archivos de audio), puede estar interesado en echar un vistazo a audiotools.sourceforge.net y a este caso de ejemplo (para macosx lion) invibe.net/ LaurentPerrinet / SciBlog / 2012-04-22Respuestas:
No intente analizar la
find
salida, excepto como último recurso. Es importante darse cuenta de que en los sistemas de archivos Unix, los nombres de los archivos no son cadenas (un error común) sino más bien blobs binarios que pueden contener cualquier carácter excepto/
el carácter nulo. Analizar los nombres de los archivos de manera segura y correcta es un dolor suficiente que el 99% de las veces solo querrás evitar hacerlo por completo (solo mira cuán peluda es lased
expresión en la respuesta de @ yarek e incluso eso no cubre todos los casos) . Afortunadamente, en este caso hay un enfoque mucho más simple:fuente
done
?sed
enfoque de la tubería es que es mucho más seguro. Todavía es más fácil de leer que la sopa de barra invertida regex, siempre que comprenda algunas construcciones básicas de secuencias de comandos de shell.$arg
variable hace que sea mucho más fácil de leer.find
invocash
con una sintaxis POSIX bastante portátil. Para obtener más detalles, puede consultar la sección sobre Expansión de parámetros , la sección sobre comandos compuestos que explica elfor
bucle y la especificación POSIXfind
. Además de esos recursos, con gusto responderé cualquier pregunta específica que tenga.En Debian y Ubuntu, puedo usarlo
rename 's/\(1\)//' *.m4a
para resolver su problema.fuente
man rename
, pero en realidad no tengorename
:-bash: rename: command not found
(which rename
no muestra nada).man -a rename
encuentra rename (2) - syscall, y rename (n) - el comando TCL. No hay rename (1) ni la utilidad en sí.rename
es un script perl incluido con los ejemplos incluidos en algunas instalaciones perl, y un par de distribuciones lo incluyen en la ruta porque es un comando conveniente. (@Hobbes quizás puedas encontrarlo en Internet)rename
es binario normal (no perl). Sin embargo, otra advertencia es que no todas las versiones derename
soporte regexes. La versión que tengo, por ejemplo, solo le permite hacer reemplazos directos de cadenas, por ejemplorename '(1)' '' *.m4a
rename
script Perl solo es instalado por Debian y sus derivados. Otros sistemas Linux tienen unarename
utilidad diferente (mostrada por Patrick). OSX no tiene ninguno.En zsh, usando zmv :
En el segundo argumento (el nuevo nombre),
$1
y se$2
refieren a los grupos entre paréntesis(PATTERN)
en el patrón fuente. Otra forma de escribir este cambio de nombre esfuente
El siguiente enfoque le brinda la capacidad de previsualizar / podar los comandos generados antes de ejecutarlos, y es muy portátil: debería funcionar no solo en un mac, no solo con bash y no solo con GNU sed; incluso en sistemas sin
find
comando (1) es posible sustituirlo pordu
(1) sin problemas.Si está satisfecho con los comandos impresos, vuelva a ejecutarlos con
| sh -x
adjuntos.Si le preocupan los espacios en los nombres de archivo, agregue otros s para escapar de todos los espacios:
Si se esperan otros caracteres especiales, se vuelve un poco más complicado:
La primera función convierte todo
'
en una forma tal que se toman literalmente cuando están en el medio de'...'
una cadena escaneada. La segunda función genera comandos mv cuyos argumentos están encerrados dentro'...'
.fuente
(
y todos los demás caracteres especiales) o agrega comillas alrededor del nombre de archivo. Intenté modificar su comando, pero no pude descubrir cómo agregar comillas alrededor de ambos nombres de archivo para elmv
comando. Uno de los resultados resultantes de su comando esmv ./The Beatles - Let It Be (MFSL LP 1-109) 24-96 Vinyl Rip/01 Two Of Us(1).m4a ./The Beatles - Let It Be (MFSL LP 1-109) 24-96 Vinyl Rip/01 Two Of Us.m4a
. Y si ejecuto ese comando me sale-bash: syntax error near unexpected token '('
.e
comando después de la sustitución. Por ejemplo,find . -name '*(1).m4a' | sed 's/\(.*\)(1).m4a$/mv & \1.m4a/e'
se ejecutará el comando sin canalizar ash -x
.Aquí hay un pequeño script que lo hace:
fuente
`find ...`