staging.inyokaproject.org

Mehrere Dateien konvertieren per Terminal

Status: Ungelöst | Ubuntu-Version: Ubuntu 20.04 (Focal Fossa)
Antworten |

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 12527

Lorz schrieb:

Und - kann man mit obigem Befehl bei der Konvertierung neben dem Verzeichnis auch noch Unterverzeichnis einbeziehen?

1
2
3
4
5
6
7
find -type f -iname \*.tex -exec sh -c '
for texdatei; do
  enc=$(file -b --mime-encoding "${texdatei}")
  echo "$enc" | fgrep -qi ISO \
  && iconv -f "$enc" -t UTF-8 -o "${texdatei}.new" "${texdatei}"
  mv -f "${texdatei}.new" "${texdatei}"
done' -- {} +

steamywindows

Avatar von steamywindows

Anmeldungsdatum:
5. Mai 2018

Beiträge: Zähle...

ISO-8859-15 und ISO-8859-1 sind 2 verschiedene Kodierungen. Bei ISO-8859-1 fehlt z. B. das Euro-Zeichen. Siehe: https://de.wikipedia.org/wiki/ISO_8859-15#ISO_8859-15_vs._-1_vs._Windows-1252_vs._Unicode

@rklm Deine Lösung ist nicht nur schöner, sondern ohne Zweifel besser! Ich war (keep-it-simple) einfach davon ausgegangen, dass es entweder ISO oder UTF-8 Dateien gibt. Das sich die ISOs dann nochmal unterscheiden könnten, habe ich nicht bedacht. Darum ist es eine ziemlich gute Idee, die tatsächliche Kodierung auszulesen und dann bei der Konvertierung anzuwenden.

@Lorz Wenn Du rekursiv durch die Verzeichnis-Struktur gehen möchtest, könntest Du z. B. probieren folgendes auszutauschen:

1
for texdatei in /home/Name/Downloads/SchwingkreisKopie/*.tex; do

gegen:

1
for texdatei in $(find /home/Name/Downloads/SchwingkreisKopie -name '*tex' -exec ls {} \;); do

find in einer for-Schleife ist evtl. nicht das eleganteste Vorgehen, müsste aber funktionieren, schätze ich.

Über wie viele Dateien unterhalten wir uns hier (so über den Daumen)?

steamywindows

Avatar von steamywindows

Anmeldungsdatum:
5. Mai 2018

Beiträge: 27

Sieht so aus, als wäre ich zu langsam mit meinen Antowrten, aber ich kämpfe noch ein wenig mit der Syntax für die Formatierung von Postings 😀

Lorz

(Themenstarter)

Anmeldungsdatum:
1. Juni 2021

Beiträge: Zähle...

Wow, vielen Dank an Euch beiden @rklm und @steamywindows! Das wird ja immer eleganter und durchdachter - jetzt auch mit angepasster Konvertierung und (optionale) Einbeziehung der Unterverzeichnisse! Herrlich! Da spiele ich gleich mal a bissl mit rum. steamywindows schrieb:

Über wie viele Dateien unterhalten wir uns hier (so über den Daumen)?

Also meine Dateiensuche für ".tex", die soweit ich es beim Scrollen überblicke auch nur tex-Dateien anzeigt (und nicht Alias oder Link zu tex-Dateien) zählt 7.959 Dateien.

Lorz

(Themenstarter)

Anmeldungsdatum:
1. Juni 2021

Beiträge: 85

rklm schrieb:

Lorz schrieb:

Und - kann man mit obigem Befehl bei der Konvertierung neben dem Verzeichnis auch noch Unterverzeichnis einbeziehen?

1
2
3
4
5
6
7
find -type f -iname \*.tex -exec sh -c '
for texdatei; do
  enc=$(file -b --mime-encoding "${texdatei}")
  echo "$enc" | fgrep -qi ISO \
  && iconv -f "$enc" -t UTF-8 -o "${texdatei}.new" "${texdatei}"
  mv -f "${texdatei}.new" "${texdatei}"
done' -- {} +

Hier hätte noch ne Sicherheitsfrage: Wie wird hier das "Start"-Verzeichnis festgelegt/die Suche begrenzt? Oder wird auf dem kompletten Rechner gesucht? Ich würde zur Sicherheit in jedem Fall den Bereich eingrenzen wollen. Es sei denn: ich kann auch das anschließende Ersetzen von "Latin1" nach "utf8" gleich für alle tex-Dateien ausführen. Dies würde ich dann eigentlich mit

1
sed -i '' 's/latin1/utf8/' /home/Name/Downloads/SchwingkreisKopie/*.tex

gemacht haben. Wird dann daraus

1
sed -i '' 's/latin1/utf8/' -iname \*.tex

wenn man alle tex-Dateien auf einmal angeht? Und/oder ist dort unpassender Unix-Code drin?

Lorz

(Themenstarter)

Anmeldungsdatum:
1. Juni 2021

Beiträge: 85

steamywindows schrieb:

@Lorz Wenn Du rekursiv durch die Verzeichnis-Struktur gehen möchtest, könntest Du z. B. probieren folgendes auszutauschen:

1
for texdatei in /home/Name/Downloads/SchwingkreisKopie/*.tex; do

gegen:

1
for texdatei in $(find /home/Name/Downloads/SchwingkreisKopie -name '*tex' -exec ls {} \;); do

find in einer for-Schleife ist evtl. nicht das eleganteste Vorgehen, müsste aber funktionieren, schätze ich.

Mmmhm, hier bekomme ich die Fehlermeldung mv: Aufruf von stat für '/home/Name/Downloads/SchwingkreisKopie/._ABVerzoegertesLampenleuchten01PH91.tex.new' nicht möglich: Datei oder Verzeichnis nicht gefunden

Danke auch für Deine Info zu den ISO-Unterschieden. Ich hatte mich dann noch gefragt, wie sich dann auswirkt, wenn man ein ISO-8859-1 als ein ISO-8859-15 behandelt beim Konvertieren. Da ISO-8859-1 weniger umfasst (und wahrscheinlich keine anderen Kodierungen als ISO-8859-15 verwendet), dürte so rum wahrscheinlich kein Fehler passieren, oder? Aber dann vielleicht andersherum, wenn ich zB das von Dir genannte Eurozeichen im Text hätte -?

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 12527

steamywindows schrieb:

1
for texdatei in $(find /home/Name/Downloads/SchwingkreisKopie -name '*tex' -exec ls {} \;); do

find in einer for-Schleife ist evtl. nicht das eleganteste Vorgehen, müsste aber funktionieren, schätze ich.

Ganz schlechte Idee! 1. gibt find ja schon den Namen aus - das ist sogar die Standardaktion. Man kann also "-exec ls {} \;" löschen. Aber 2. (siehe die Links auf meiner Nutzerseite zum Thema ls). Sicherer ist eine Übergabe, wie ich das mit dem Shell-Skript gemacht habe.

Lorz schrieb:

Hier hätte noch ne Sicherheitsfrage: Wie wird hier das "Start"-Verzeichnis festgelegt/die Suche begrenzt? Oder wird auf dem kompletten Rechner gesucht?

Nein. Wenn man nix angibt, dann startet find im aktuellen Verzeichnis, sonst halt in den Verzeichnissen, die man angibt. Schau doch auf die Manpage. Ist alles erklärt. Man darf Dokumentation lesen. ☺ Genau so, wie man Dinge einfach ausprobieren darf. Hint hint... 😉

Lorz

(Themenstarter)

Anmeldungsdatum:
1. Juni 2021

Beiträge: 85

rklm schrieb:

Für die Lesbarkeit:

1
2
3
4
5
for texdatei in /home/Name/Downloads/SchwingkreisKopie/*.tex; do
  file -b --mime-encoding "${texdatei}" | fgrep -qi ISO \
  && iconv -f ISO-8859-15 -t UTF-8 -o "${texdatei}.new" "${texdatei}"
  mv -f "${texdatei}.new" "${texdatei}"
done

Man könnte sich auch noch das erkannte Encoding merken:

1
2
3
4
5
6
for texdatei in /home/Name/Downloads/SchwingkreisKopie/*.tex; do
  enc=$(file -b --mime-encoding "${texdatei}")
  echo "$enc" | fgrep -qi ISO \
  && iconv -f "$enc" -t UTF-8 -o "${texdatei}.new" "${texdatei}"
  mv -f "${texdatei}.new" "${texdatei}"
done

Auch hier bekomme ich für beide Skripte eine Fehlermeldung, wenn ich das Skript erneut über das Verzeichnis laufen lasse (sich also nun schon utf8-formatierte tex-Dateien drin befinden): mv: Aufruf von stat für '/home/Name/Downloads/SchwingkreisKopie/ABSchwingkreisEinfuehrungPH01in2022.tex.new' nicht möglich: Datei oder Verzeichnis nicht gefunden

Lorz

(Themenstarter)

Anmeldungsdatum:
1. Juni 2021

Beiträge: 85

rklm schrieb:

Nein. Wenn man nix angibt, dann startet find im aktuellen Verzeichnis, sonst halt in den Verzeichnissen, die man angibt. Schau doch auf die Manpage. Ist alles erklärt. Man darf Dokumentation lesen. ☺ Genau so, wie man Dinge einfach ausprobieren darf. Hint hint... 😉

Es tut mir leid, dass ich soviel Rückfragen habe. Im obigen Fall wollte ich nicht einfach ausprobieren, falls der Befehl dann auf die gesamte Festplatte losgegangen wäre und ich tausende Fehlermeldungen bekomme oder sonst irgendwas passiert, was ich nicht bedenke. Und leider habe ich bis jetzt ja noch geschafft, eine fehlerfreies Skript auszuführen, dass auch noch Unterordner einbezieht.

Ich habe jetzt probiert in dem funktionierenden Skript von steamywindows

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
#!/bin/sh

Pfad="/home/Name/Downloads/SchwingkreisKopie"
set -e

for texdatei [mark]in "${Pfad}"/*.tex[/mark]
do
if [ $(file "${texdatei}" | grep -c ISO) -eq 1 ]
then
echo -e "${texdatei} ist im ISO-Format und wird konvertiert."
iconv -f ISO-8859-15 -t UTF-8 "${texdatei}" > "${texdatei}.new"
mv -f "${texdatei}.new" "${texdatei}"
else
echo -e "${texdatei} ist nicht ISO-formatiert und wird in Ruhe gelassen."
fi
done

exit 0

auch rekursiv suchen zu lassen, indem ich das in "${Pfad}"/*.tex zu ersetzen durch -iname \*.tex und -name *.tex, aber da bekomme ich die Fehlermeldung 5: Syntax error: word unexpected (expecting "do")

Doc_Symbiosis

Avatar von Doc_Symbiosis

Anmeldungsdatum:
11. Oktober 2006

Beiträge: 4212

In Zeile 6 muss ein Semikolon ans Ende der Zeile, ebenso in Zeile 8.

Wenn Du noch nicht so versiert mit Skripten bist, empfehle ich Dir, shellcheck zu nutzen.

Lorz

(Themenstarter)

Anmeldungsdatum:
1. Juni 2021

Beiträge: 85

Doc_Symbiosis schrieb:

In Zeile 6 muss ein Semikolon ans Ende der Zeile, ebenso in Zeile 8.

Wenn Du noch nicht so versiert mit Skripten bist, empfehle ich Dir, shellcheck zu nutzen.

Also das Skript, so wie es ist, funktioniert ja ohne Fehlermeldung, auch ohne Semikolon am Ende von Zeile 6 und 8. Ich habe es in shellcheck kopiert - cooles Tool auf jeden Fall! Allerdings wird auch dort - zumindest nicht direkt - kein fehlendes Semikolon moniert. Jedoch zwei verschiedene andere Fehler, die mir jedoch nix sagen. Ich sehe die Verlinkung der Fehlernummer. Aber auch die hilft mir nicht. Aber wie gesagt, das obige Skript, wenn ich nix verändere, läuft fehlerfrei.

Ich müsste jetzt nur wissen, wie ich darin auch die Unterverzeichnisse einbeziehen.

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 12527

Lorz schrieb:

Auch hier bekomme ich für beide Skripte eine Fehlermeldung, wenn ich das Skript erneut über das Verzeichnis laufen lasse (sich also nun schon utf8-formatierte tex-Dateien drin befinden): mv: Aufruf von stat für '/home/Name/Downloads/SchwingkreisKopie/ABSchwingkreisEinfuehrungPH01in2022.tex.new' nicht möglich: Datei oder Verzeichnis nicht gefunden

Ja, mein Fehler. Sollte so sein:

1
2
3
4
5
6
for texdatei in /home/Name/Downloads/SchwingkreisKopie/*.tex; do
  enc=$(file -b --mime-encoding "${texdatei}")
  echo "$enc" | fgrep -qi ISO \
  && iconv -f "$enc" -t UTF-8 -o "${texdatei}.new" "${texdatei}" \
  && mv -f "${texdatei}.new" "${texdatei}"
done

Der mv darf natürlich nur ausgeführt werden, wenn das Encoding geändert wurde.

Doc_Symbiosis

Avatar von Doc_Symbiosis

Anmeldungsdatum:
11. Oktober 2006

Beiträge: 4212

Also das Skript, so wie es ist, funktioniert ja ohne Fehlermeldung, auch ohne Semikolon am Ende von Zeile 6 und 8.

Ach stimmt, das Semikolon braucht man nur, wenn das do bzw. then in der gleichen Zeile stehen soll.

Und zu dem shellcheck: Einiges sind eben auch nur Warnungen bzw. Hinweise. Das müssen nicht alles echte Fehler sein. Alles was rot markiert wird, da sollte man wirklich aufpassen. Die grünen Hinweise kann man auch oft ignorieren.

Lorz

(Themenstarter)

Anmeldungsdatum:
1. Juni 2021

Beiträge: 85

Doc_Symbiosis schrieb:

Und zu dem shellcheck: Einiges sind eben auch nur Warnungen bzw. Hinweise. Das müssen nicht alles echte Fehler sein. Alles was rot markiert wird, da sollte man wirklich aufpassen. Die grünen Hinweise kann man auch oft ignorieren.

Ja, stimmt, das waren nur Ausrufzeichenschilder.

Lorz

(Themenstarter)

Anmeldungsdatum:
1. Juni 2021

Beiträge: 85

rklm schrieb:

Lorz schrieb:

Und - kann man mit obigem Befehl bei der Konvertierung neben dem Verzeichnis auch noch Unterverzeichnis einbeziehen?

1
2
3
4
5
6
7
find -type f -iname \*.tex -exec sh -c '
for texdatei; do
  enc=$(file -b --mime-encoding "${texdatei}")
  echo "$enc" | fgrep -qi ISO \
  && iconv -f "$enc" -t UTF-8 -o "${texdatei}.new" "${texdatei}"
  mv -f "${texdatei}.new" "${texdatei}"
done' -- {} +

Wow, das funktioniert!! Super! Herzlichen Dank! Das interessiert nicht nur mich, sondern auch viele andere, die ältere Latexdateien auf ihren Festplatten haben und mal aufräumen wollen.

Ich weiß, dass sich dieser Thread jetzt schon a bissl zieht. Aber wenn ich jetzt noch ne Ausweitung zur rekursiven Suchen und Ersetzen Möglichkeit für unteren Befehl hätte, der keine Fehlermeldung bringt:

1
for texdatei in `find /home/Name/Downloads/SchwingkreisKopie/ -name "*.tex" -print`; do

funktioniert, aber bringt die Fehlermeldung mit sich mv: Aufruf von stat für '/home/Name/Downloads/SchwingkreisKopie/._ABSchwingkreissimulationPH01in2022.tex.new' nicht möglich: Datei oder Verzeichnis nicht gefunden

Dann wäre das Thema abgeschlossen.