it-swarm.com.de

Umbenennen von Dateien in der Befehlszeile und in Xargs

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?

22
Cripto

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.

19
Tim Pote

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.

49
Schleis

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.

10
Dethe

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.

6
Matej

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:

  1. in diesem Verzeichnis finden Sie Dateien mit dem Namen * .svg.png. Die Datei -print0 wird in der Standardausgabe gedruckt
  2. sed ändert die Standardausgabe, tauscht im Wesentlichen .svg.png mit nichts aus, daher würde ich Folgendes erhalten: file1/file2/file3/file4
  3. xargs -0, um die Daten aus sed zu erhalten, -I referenziert den Dateinamen ohne die Erweiterung, dann mv ursprünglichen Dateinamen auf neuen Dateinamen. Das Word namePrefix ist nichts Besonderes, wollte es nur klarstellen.

EDIT

Ich weiß jetzt, dass dies der komplizierteste Weg ist, dies zu tun. Man kann einfach den Umbenennungsbefehl verwenden.

rename 's/svg\.png/.png/' *
3
Paul J

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:

  • durch das Umbenennen wird die Datei nicht komprimiert (verwenden Sie also convert anstelle von mv)
  • ls \.png$ | xargs Behandelt keine Leerzeichen im Pfad/Dateinamen
  • find . 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)
  • Der Parameter -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 geht
3
Alexey K.

Meine 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

Erläuterung

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
1
joshperry

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
0
SergioAraujo