linux - renombrar - sed sustituir caracteres especiales
Lote renombrando archivos en lĂnea de comandos y Xargs (7)
¿Cómo puedo cambiar el nombre del archivo para que pueda tener una sola extensión?
cd dir/with/messedup/files
for file in *.png.jpg; do
mv "$file" "${file%.png.jpg}.jpg"
done
en el futuro, usando xargs, ¿cómo cambio la extensión del archivo simular al segundo comando?
Que yo sepa, eso no se puede hacer. La mejor manera de hacerlo sería utilizar un bucle for con sustitución de parámetros muy similar al anterior:
for file in *.png; do
convert "$file" -resize "${file%.png}.jpg"
done
Si tiene archivos en los subdirectorios que desea convertir, puede canalizar la find
a un bucle de while read
:
find . -type f -name ''*.png'' |
while read file; do
convert "$file" -resize "${file%.png}.jpg"
done
NOTA: En general, se considera una mala idea usar la salida de ls
en un script de shell. Si bien su ejemplo podría haber funcionado bien, hay muchos ejemplos en los que no funciona. Por ejemplo, si sus nombres de archivo tienen nuevas líneas (lo que permite Unix), ls
probable que no los escape por usted. (Eso realmente depende de su implementación, que es otra razón para no usar ls
en los scripts; su comportamiento varía mucho de una casilla a otra). Obtendrá resultados más consistentes si usa find
en un ciclo de lectura mientras está o archivo globbing (por ejemplo, *.png
) en un bucle for.
Por lo tanto, tengo la siguiente estructura:
.
..
a.png
b.png
c.png
Corrí un comando para redimensionarlos
ls | xargs -I xx convert xx -resize xx.jpg
Ahora mi dir se ve asi
.
..
a.png.jpg
a.png
b.png.jpg
b.png
c.png.jpg
c.png
La primera pregunta es, ¿cómo puedo cambiar el nombre del archivo para que pueda tener una sola extensión? No dos (básicamente, ¿cómo puedo limpiar mi error original)?
La segunda pregunta es, en el futuro, usando xargs, ¿cómo cambio la extensión del archivo simular al segundo comando?
Esto también se puede hacer con xargs
y sed
para cambiar la extensión del archivo.
ls | grep /.png$ | sed ''p;s//.png//.jpg/'' | xargs -n2 mv
Puede imprimir el nombre del archivo original junto con lo que desea que sea el nombre del archivo. Luego haga que xargs use esos dos argumentos en el comando de movimiento. Para el de una sola línea, también agregué un grep para filtrar todo lo que no sea un archivo * .png.
Llegas tarde a la fiesta, pero aquí es cómo puedes cambiar el nombre de los archivos con xargs. Digamos que tienes un montón de archivos con el nombre fileN.svg.png y quieres nombrarlos fileN.png donde N podría ser una serie de enteros:
ls *.svg.png | xargs basename -s .svg.png | xargs -I {} mv {}.svg.png {}.png
El primer xargs usa el nombre base para eliminar tanto .svg como .png para obtener un filenameN
simplemente. El segundo xargs recibe ese nombre simple y utiliza el reemplazo para cambiar el nombre del archivo.
Llegué tarde a esta fiesta por alrededor de 3 años, tuve un problema similar que descubrí yo mismo. Tenía una lista de archivos png que convertí usando inkscape, porque el soporte de svg de ImageMagick es deficiente.
Originalmente los convertí haciendo:
find . -name "*.svg" -exec inkscape {} --export-png={}.png
Lo que, por supuesto, llevó a la misma cuestión como publicado anteriormente.
file1.svg
file1.svg.png
file2.svg
file2.svg.png
file3.svg
file3.svg.png
file4.svg
file4.svg.png
Quería cambiar el nombre de * .svg.png a * .png, esto es lo que terminé con ...
find . -name "*.svg.png" -print0 | sed ''s/.svg.png//g'' | xargs -0 -I namePrefix mv namePrefix.svg.png namePrefix.png
Esto hace tres cosas:
- encuentre en este directorio los archivos llamados * .svg.png, el -print0 imprime en la salida estándar
- sed modifica la salida estándar, básicamente intercambia .svg.png con nada, así que obtendría: file1 / file2 / file3 / file4
- xargs -0 para obtener los datos de sed, -I hace referencia al nombre del archivo sin la extensión, luego mv original al nuevo nombre del archivo. La palabra nombrePrefijo no es nada especial, solo quería dejarlo claro.
EDITAR
Ahora me doy cuenta de que esta es la forma más complicada de hacer esto. Uno puede simplemente usar el comando renombrar.
rename ''s/svg/.png/.png/'' *
Mi solución es similar a muchas de las soluciones xarg, y particularmente similar a la de Schleis.
La diferencia aquí es una manipulación total de expresiones regulares con referencias de coincidencia y comandos sed que ignoran correctamente los archivos que no coinciden, por lo que no es necesario que prefiltrar su anuncio.
Esto también es seguro para archivos con espacios y shell meta.
Cambie /2
en el reemplazo a cualquier extensión deseada.
ls |
sed -nE ''s/Rick/.and/.Morty/.(S03E[0-9]{2})/..*(/.[a-z0-9]{3})/"&" "Rick and Morty /1/2"/;T;p'' |
xargs -n 2 mv
Explicación
El comando -n
arg le indica que no imprima nada por defecto, el comando T
dice saltar al final de la secuencia de comandos si el comando anterior s
no hizo un reemplazo, el comando p
imprime el espacio del patrón (solo presione si el comando s
partidos).
El &
en el reemplazo es una referencia al contenido de la coincidencia del nombre de archivo original.
Si reemplazamos mv
en el comando con bash -c ''echo "run($#) $@"'' bash
entonces podemos ver la cantidad de veces que se llamará mv
y con el valor y el recuento de parámetros:
$ ls |
sed -nE ''s/Rick/.and/.Morty/.(S03E[0-9]{2})/..*(/.[a-z0-9]{3})/"&" "Rick and Morty /1/2"/;T;p'' |
xargs -n 2 bash -c ''echo "run($#) $@"'' bash
run(2) Rick.and.Morty.S03E02.720p.HDTV.x264-BATV.mkv Rick and Morty S03E02.mkv
run(2) Rick.and.Morty.S03E03.720p.HDTV.x264-BATV.mkv Rick and Morty S03E03.mkv
run(2) Rick.and.Morty.S03E04.720p.HDTV.x264-BATV.mkv Rick and Morty S03E04.mkv
run(2) Rick.and.Morty.S03E05.HDTV.x264-BATV[ettv].mkv Rick and Morty S03E05.mkv
run(2) Rick.and.Morty.S03E06.720p.HDTV.x264-BATV.mkv Rick and Morty S03E06.mkv
run(2) Rick.and.Morty.S03E06.HDTV.x264-BATV.mkv Rick and Morty S03E06.mkv
run(2) Rick.and.Morty.S03E07.720p.HDTV.x264-BATV[ettv].mkv Rick and Morty S03E07.mkv
run(2) Rick.and.Morty.S03E08.720p.HDTV.x264-BATV.mkv Rick and Morty S03E08.mkv
run(2) Rick.and.Morty.S03E09.720p.HDTV.x264-BATV.mkv Rick and Morty S03E09.mkv
run(2) Rick.and.Morty.S03E10.720p.HDTV.x264-BATV.mkv Rick and Morty S03E10.mkv
Para limpiar su error, pruebe la utilidad de rename
. Consulte la página de manual para más detalles.
En su caso, rename ''.png.jpg'' ''.jpg'' ./*
si su directorio actual está configurado correctamente.
Dado que tienes convert
disponibles, mogrify
también te has mogrify
( imagemagick
suite). Cada vez que quiero hacer esto, copio los archivos en un directorio diferente y en su lugar utilizo mogrify
. Por lo general, necesito esto solo para cambiar el tamaño, pero si también cambias el formato de la imagen, mogrify
manejará los nombres de archivo (creará archivos nuevos con los nombres de archivo adecuados).
Lo utilizarías como mogrify -format jpg -resize [size] ./*.png
. No estoy seguro de qué se supone que haga el cambio de -resize
sin geometría. No está documentado y no funciona en mi máquina.
Como Tim Pote razonó, no creo que puedas hacer que los xargs manejen nombres de archivos y extensiones por separado.
find ./xx -name "*.png" -print0 |sed ''s/.png$//g''|xargs -0 -I% mv %.png %.jpg