¿Cómo puedo ejecutar mogrify sobre los 3 millones de archivos JPG?


1

Tengo 3 millones de archivos JPG almacenados en un servidor Linux CentOS 6.

Quiero cambiar la calidad al tamaño de archivo% 50 sobre 1 megabyte. Escribí este comando pero recibí el error "lista de argumentos demasiado larga":

$ find -type f -name "*..jpg" -size +1M | xargs mogrify -quality 50 *.jpg
bash: /usr/bin/xargs: Argument list too long

¿Cómo puedo cambiar la calidad de millones de archivos?


2
¿Por qué agregas *.jpga xargs? Obtendrá los archivos de find.
choroba

Respuestas:


2

xargsadmite un -nargumento para limitar la cantidad de argumentos pasados ​​a lo que llama:

find -type f -name '*.jpg' -size +1M -print0 | xargs -0 -n1 mogrify -quality 50

Esto lanzará mogrify una vez por imagen. Como mogrify solo puede procesar un archivo a la vez, este es el camino a seguir.


mogrifyLa documentación muestra ejemplos con *.jpg.
choroba

Ah, confié ciegamente en la página de manual: "SINOPSIS mogrify [opciones] input-file", lo que indica que solo es compatible con uno.
Dennis Kaarsemaker

1

Cuando use findy xargs, no necesita nombrar los archivos xargs. Obtendrá la lista de archivos de find:

find -print0 -type f -name '*.jpg' -size +1M | xargs -0 -n100 mogrify -quality 50

-n100procesará las imágenes por 100s. -print0y -0hará que la tubería funcione incluso si los nombres de archivo contienen espacios en blanco.

También puede llamar mogrifydirectamente desde find, idealmente si admite el +final de exec:

find  -type f -name '*.jpg' -size +1M -exec mogrify -quality 50 {} +

Esto todavía hará que la lista de argumentos sea demasiado larga en el primer comando, si todos se pasan a xargs en uno. Además, debe canalizar de finda xargscon find ... -print0 | xargs -0.
slhck

Bueno, afortunadamente, find puedo hacerlo todo . : D En lugar de terminar el comando -exec con +, también se puede terminar con ;. Esto ejecuta el comando una vez por resultado. ¡No te olvides de escapar ;!
Daniel B

@DanielB: ¿Cuál es la ventaja de ;terminar +en este caso?
choroba

1
No da como resultado una línea de comando que sea demasiado larga. Aunque findya podría evitar eso, quién sabe. También es adecuado para comandos que no aceptan entrada por lotes.
Daniel B

Bueno, aunque puede ser un poco spam, descubrí xargsy find, de hecho, soy lo suficientemente inteligente como para dividir la colección de argumentos automáticamente.
Daniel B

0

Una solución multiplataforma con Python + convert: convertirá todos los archivos PDF del directorio actual en archivos PNG (puede cambiar a JPG si lo prefiere) multiproceso.

from __future__ import print_function
import os
import glob
import multiprocessing      

def convert_to_png(pdf_filepath):
    '''
    Convert PDF file to PNG file
    '''
    png_filepath = '{0}.png'.format(pdf_filepath[:-4])
    print('pdf_filepath: {0}'.format(pdf_filepath))
    print('png_filepath: {0}'.format(png_filepath))
    command = 'convert -background white -alpha off -geometry 1600x1600 -density 200x200 -quality 100 -resize 800x {0} {1}'.format(pdf_filepath, png_filepath)
    print(command)
    os.system(command)

def main():
    pdf_filepaths = glob.iglob(os.path.join('.','*.pdf'))
    pool = multiprocessing.Pool(processes=4)
    pool.map(convert_to_png, pdf_filepaths)
    pool.close()
    pool.join()   
    print('done')

if __name__ == "__main__":
    main()
    #cProfile.run('main()') # if you want to do some profiling

Esto requiere que se instalen Imagemagick y Ghostscript . Funciona en Linux / Mac OS X / Microsoft Windows.

Si prefiere agregar el nombre de archivo en cada imagen, puede reemplazar el comando convert_to_png()por:

command = 'convert  -background white -alpha off -geometry 1600x1600 -density 200x200 -quality 100 -annotate +50+50 {2} -resize 800x {0} {1}'.format(pdf_filepath, png_filepath, os.path.basename(pdf_filepath))

(Ver -anotar documentación)


0

Como se mencionó en SO , también podría hacer:

$ find -type f -name "*..jpg" -size +1M > my_jpeg.txt
$ mogrify -quality 50 @my_jpegs.txt
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.