Wie kann ich mogrify über die 3 Millionen JPG-Dateien ausführen?

2215
Metin Çelik

Ich habe 3 Millionen JPG-Dateien auf einem Linux CentOS 6-Server gespeichert.

Ich möchte die Qualität in% 50 Dateigröße über 1 Megabyte ändern. Ich habe diesen Befehl geschrieben, erhielt jedoch die Fehlermeldung "Argumentliste zu lang":

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

Wie kann ich die Qualität von Millionen von Dateien ändern?

1
Warum fügen Sie `* .jpg` zu` xargs` hinzu? Die Dateien werden von "find" abgerufen. choroba vor 10 Jahren 2

3 Antworten auf die Frage

2
Dennis Kaarsemaker

xargsunterstützt ein -nArgument, um die Anzahl der übergebenen Argumente zu begrenzen:

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

Dadurch wird mogrify einmal pro Bild gestartet. Da mogrify jeweils nur eine Datei verarbeiten kann, ist dies der richtige Weg.

Die Dokumentation von "mogrify" zeigt Beispiele mit "* .jpg". choroba vor 10 Jahren 0
Ah, ich habe blind der Manpage vertraut: "SYNOPSIS mogrify [Optionen] Eingabedatei" - zeigt an, dass sie nur eine unterstützt. Dennis Kaarsemaker vor 10 Jahren 0
1
choroba

Wenn Sie findund verwenden xargs, müssen Sie die Dateien nicht benennen xargs. Die Liste der Dateien wird abgerufen von find:

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

-n100verarbeitet die Bilder um 100s. -print0und -0die Pipe funktioniert auch dann, wenn die Dateinamen Leerzeichen enthalten.

Sie können auch mogrifydirekt von find aus anrufen, am besten, wenn die +Endung für Folgendes unterstützt wird exec:

find -type f -name '*.jpg' -size +1M -exec mogrify -quality 50 {} + 
Dadurch wird die Argumentliste im ersten Befehl immer noch zu lang, wenn alle in einem xargs übergeben werden. Außerdem sollten Sie von `find` nach` xargs` mit `find ... -print0 | xargs -0`. slhck vor 10 Jahren 0
Zum Glück kann `find` * alles *. : D Statt den Befehl -exec mit '+' zu beenden, kann er auch mit `;` beendet werden. Dadurch wird der Befehl einmal pro Ergebnis ausgeführt. Vergiss nicht zu fliehen. Daniel B vor 10 Jahren 0
@DanielB: Was ist der Vorteil von `;` gegenüber `+` in diesem Fall? choroba vor 10 Jahren 0
Es führt nicht zu einer Befehlszeile, die zu lang ist. Auch wenn "find" vielleicht schon funktioniert, wer weiß. Es eignet sich auch für Befehle, die keine Batch-Eingabe akzeptieren. Daniel B vor 10 Jahren 1
Nun, obwohl es ein bisschen spammig sein kann, habe ich entdeckt, dass xargs und find in der Tat klug genug sind, die Argumentsammlung automatisch aufzuteilen. Daniel B vor 10 Jahren 0
0
Franck Dernoncourt

Eine plattformübergreifende Lösung mit Python + convert: Alle PDF-Dateien des aktuellen Verzeichnisses werden in PNG-Dateien (Sie können in JPG wechseln, wenn Sie dies vorziehen) multithreaded konvertiert.

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 = '.png'.format(pdf_filepath[:-4]) print('pdf_filepath: '.format(pdf_filepath)) print('png_filepath: '.format(png_filepath)) command = 'convert -background white -alpha off -geometry 1600x1600 -density 200x200 -quality 100 -resize 800x '.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 

Dies erfordert, dass Imagemagick und Ghostscript installiert sind. Funktioniert unter Linux / Mac OS X / Microsoft Windows.

Wenn Sie den Dateinamen lieber zu jedem Bild hinzufügen möchten, können Sie den Befehl ersetzen convert_to_png()durch:

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

(Siehe -notieren Dokumentation)