Ich habe also folgende Struktur:
.
..
a.png
b.png
c.png
Ich habe einen Befehl ausgeführt, um die Größe zu ändern
ls | xargs -I xx convert xx -resize xx.jpg
Jetzt sieht mein dir so aus
.
..
a.png.jpg
a.png
b.png.jpg
b.png
c.png.jpg
c.png
Die erste Frage ist, wie ich die Datei umbenenne, so dass ich nur eine Erweiterung haben kann. Nicht zwei (Wie kann ich meinen ursprünglichen Fehler aufräumen)?
Die zweite Frage ist die Verwendung von xargs in der Zukunft. Wie kann ich die Erweiterung der Datei simular in den zweiten Befehl ändern?
wie benenne ich die Datei um, so dass ich nur eine Erweiterung haben kann.
cd dir/with/messedup/files
for file in *.png.jpg; do
mv "$file" "${file%.png.jpg}.jpg"
done
wie kann ich in der Zukunft mit xargs die Erweiterung der Datei simular in den zweiten Befehl ändern?
Meines Wissens kann das nicht gemacht werden. Der beste Weg wäre es, eine for-Schleife mit Parametern zu verwenden, ähnlich wie oben:
for file in *.png; do
convert "$file" -resize "${file%.png}.jpg"
done
Wenn Sie Dateien in Unterverzeichnissen haben, die Sie konvertieren möchten, können Sie find
an eine while read
-Schleife übergeben:
find . -type f -name '*.png' |
while read file; do
convert "$file" -resize "${file%.png}.jpg"
done
HINWEIS:Es wird im Allgemeinen als schlechte Idee angesehen , die Ausgabe von ls
in einem Shell-Skript zu verwenden. Während Ihr Beispiel vielleicht gut funktioniert hat, gibt es viele Beispiele, bei denen dies nicht der Fall ist. Wenn beispielsweise in Ihren Dateinamen Zeilenumbrüche enthalten waren (was Unix zulässt), wird ls
diese wahrscheinlich nicht für Sie entziehen. (Das hängt tatsächlich von Ihrer Implementierung ab. Dies ist ein weiterer Grund, ls
nicht in Skripts zu verwenden; das Verhalten ist von Box zu Box sehr unterschiedlich.) Sie erhalten konsistentere Ergebnisse, wenn Sie find
in einer while-read-Schleife oder verwenden Dateiblobbing (zB *.png
) in einer for-Schleife.
Dies kann auch mit xargs
und sed
durchgeführt werden, um die Dateierweiterung zu ändern.
ls | grep \.png$ | sed 'p;s/\.png/\.jpg/' | xargs -n2 mv
Sie können den ursprünglichen Dateinamen zusammen mit dem gewünschten Dateinamen drucken. Dann sollten xargs diese beiden Argumente im Verschiebungsbefehl verwenden. Für den Einzeiler fügte ich auch ein grep hinzu, um etwas herauszufiltern, das keine * .png-Datei ist.
Komme spät zur Party, aber hier kannst du Dateien mit xargs umbenennen. Angenommen, Sie haben eine Reihe von Dateien namens fileN.svg.png, und Sie möchten sie fileN.png nennen, wobei N eine Reihe von Ganzzahlen sein kann:
ls *.svg.png | xargs basename -s .svg.png | xargs -I {} mv {}.svg.png {}.png
Die ersten xargs verwenden basename, um sowohl .svg als auch .png zu entfernen, um nur eine filenameN
zu erhalten. Das zweite xargs erhält diesen bloßen Namen und verwendet die Ersetzung, um die Datei umzubenennen.
Um Ihren Fehler zu beheben, probieren Sie das Dienstprogramm rename
aus. Überprüfen Sie die Manpage für Details.
In Ihrem Fall würden Sie rename '.png.jpg' '.jpg' ./*
tun, wenn Ihr aktuelles Verzeichnis entsprechend eingestellt ist.
Da Sie convert
zur Verfügung haben, gehe ich davon aus, dass Sie auch mogrify
(imagemagick
suite) haben. Wenn ich dies tun möchte, kopiere ich die Dateien in ein anderes Verzeichnis und verwende stattdessen mogrify
. Normalerweise brauche ich dies nur für die Größenänderung. Wenn Sie jedoch auch das Bildformat ändern, wird mogrify
die Dateinamen behandeln (neue Dateien mit den richtigen Dateinamen erstellen).
Sie würden es als mogrify -format jpg -resize [size] ./*.png
verwenden. Ich bin mir nicht sicher, was -resize
ohne Geometrieargumente tun soll. Es ist nicht dokumentiert und funktioniert nicht auf meinem Rechner.
Tim Pote meinte, ich glaube nicht, dass Sie Xargs mit Dateinamen und Erweiterungen getrennt behandeln lassen können.
Ich bin um drei Jahre zu spät zu dieser Party gekommen, ich hatte gerade ein ähnliches Problem, das ich selbst herausgefunden habe. Ich hatte eine Liste von PNG-Dateien, die ich mit Inkscape konvertiert habe, da die svg-Unterstützung von ImageMagick schlecht ist.
Ich habe sie ursprünglich konvertiert, indem ich
find . -name "*.svg" -exec inkscape {} --export-png={}.png
Was natürlich zu dem gleichen Problem geführt hat, das oben beschrieben wurde.
file1.svg
file1.svg.png
file2.svg
file2.svg.png
file3.svg
file3.svg.png
file4.svg
file4.svg.png
Ich wollte * .svg.png in * .png umbenennen.
find . -name "*.svg.png" -print0 | sed 's/.svg.png//g' | xargs -0 -I namePrefix mv namePrefix.svg.png namePrefix.png
Dies bewirkt drei Dinge:
EDIT
Ich weiß jetzt, dass dies der komplizierteste Weg ist, dies zu tun. Man kann einfach den Umbenennungsbefehl verwenden.
rename 's/svg\.png/.png/' *
Nach einigen Nachforschungen zu ähnlichen Aufgaben hier ist mein Code:
find . -maxdepth 1 -name '*.png' -print0 | sed 's/.png//g' | xargs -0 -I% -n 1 -P 8 convert -quality 100 %.png %.jpg
Argumentation:
convert
anstelle von mv
)ls \.png$ | xargs
Behandelt keine Leerzeichen im Pfad/Dateinamenfind .
Sucht in Unterordnern, verwenden Sie also -maxdepth 1
convert
verwendet keine verfügbaren CPUs, also -P8
(oder -P other
)sed
ohne 'g'
am Ende ersetzt nicht alle Dateien (nur eine)sed 's/.png//g'
Hinterlässt keine Erweiterung (Basisname konnte auch funktionieren, tat es aber nicht nach -print0
)parallel
- möglicherweise bessere Lösung, funktionierte aber nicht auf meiner Ubuntu 18.04-Bash 4.4%
Ist das kleinste verbreitete Substitutionssymbol (vergleiche mit {} xx namePrefix
)-n2
Ist gut für xargs
, hat aber mit -print0
Nicht richtig funktioniert (n
Anzahl der Einträge, die nach xargs
genommen und übergeben werden sollen )-quality 100
Standardmagiequalität ist 92 (was in Ordnung ist), hier 100%, um zu vermeiden, dass etwas verloren gehtMeine Lösung ist ähnlich wie viele der Xarg-Lösungen und besonders ähnlich wie die von Schleis.
Der Unterschied hier ist eine vollständige Regex-Manipulation mit Übereinstimmungsreferenzen und sed-Befehlen, die Dateien, die nicht übereinstimmen, richtig ignorieren, sodass Sie Ihren Eintrag nicht vorfiltern müssen.
Dies ist auch für Dateien mit Leerzeichen und Shell-Meta sicher.
Ändern Sie \2
in der gewünschten Erweiterung.
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
Der Befehl -n
arg sagt, dass standardmäßig nichts gedruckt werden soll. Der Befehl T
sagt zum Ende des Skripts springen, wenn der vorherige Befehl s
keinen Ersatz ausführte. Der Befehl p
gibt den Musterbereich aus (wird nur getroffen, wenn der Befehl s
übereinstimmt.) ).
Der &
in der Ersetzung ist ein Verweis auf den Inhalt des ursprünglichen Dateinamens.
Wenn wir mv
im Befehl durch bash -c 'echo "run($#) [email protected]"' bash
ersetzen, können Sie sehen, wie oft mv
aufgerufen wurde, und mit Parameter Anzahl und Wert:
$ 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($#) [email protected]"' 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
Mein Versuch von: https://www.tecmint.com/linux-image-conversion-tools/
ls -1 *.png | xargs -n 1 bash -c 'convert "$0" "${0%.png}.jpg"'
Parallel verwenden
parallel convert '{}' '{.}.jpg' ::: *.png