echo, Dateisystem und Umlaute ...

gantim

Aktives Mitglied
Thread Starter
Dabei seit
27.08.2007
Beiträge
769
Reaktionspunkte
88
Derzeit versuche ich ein bash-shellskript zu erstellen, das mir Playlists für einen Billig-Player erzeugt. Das klappt mittlerweile, nur sobald ein Umlaut vorkommt geht nichts.

Faszinierenderweise kommt nicht mal Textedit mit dem Output klar!

schwan:AGPTek A02 tag$ ls Music/Der\ Bär\ im\ grossen\ blauen\ Haus\ 10/
01 Zeit Für Alle.mp3 02 Übung Macht Den Meister.mp3
schwan:AGPTek A02 tag$ ls Music/Der\ Bär\ im\ grossen\ blauen\ Haus\ 10/>test.txt
Inhalt Text.txt, angezeigt mit Textedit und dann copy/paste:
01 Zeit FuÃàr Alle.mp3
02 UÃàbung Macht Den Meister.mp3
cat test.txt geht aber wieder ...

Es scheint eine ungewöhnliche Umlaut-UTF8-Kodierung zu sein, die OSX benutzt. Man kann es auf mehrere Weisen darstellen: Das Standard-Ä, oder erst A und dann zwei UTF-8-Modifier, die aus dem A ein Ä machen, und das benutzt das Dateisystem.

Nun meine Frage: Wie bekomme ich das sauber konvertiert? Vermutlich braucht der Player latin1. Das richtige direkte Ä hilft nicht, das habe ich schon im Editor eingetippt. Aber das muss ich dann noch austesten, wenn ich konvertieren kann. Aber iconv, das Standard-Tool für bash, hilft auch nicht! Das stoppt die Konvertierung beim ersten Umlaut :(

Muss ich wirklich sed nehmen, auf die Hexcodes gehen und direkt ersetzen der 7 Zeichen äöüÄÖÜß? Derzeit würde mir das helfen. Aber schön fände ich das nicht.
 
Es wird immer verrückter! sed auf OSX kann kein Hex-Zeichen!

#!/bin/bash
echo Test > aaäöüÄÖÜß
ls aa*
ls aa*>test.txt
ls aa*|sed 's/\x61\xcc\x88/\xE4/g'>>test.txt
ls aa*|sed 's/\x61/bla/g'>>test.txt
ls aa*|sed 's/\x6f\xcc\x88/ö/g'>>test.txt
cat test.txt

Das ist immer das gleiche, weil \xXX wohl nicht geht ...
Ich will doch nur 7 Zeichen ersetzen, so dass latin-1 rauskommt :(

Wie bekomme ich das denn nun hin? Irgendein Zwischenzeichen, und dann tr oder sowas? Kann der das denn, wenn sed nicht geht? Also sowas ...
 
man iconv

Damit sollte es eigentlich gehen, zwischen verschiedenen Codierungen zu wechseln.
 
Sollte, genau. Das war ja auch mein erster Versuch zu konvertieren. Wie in meinem ersten Posting erwähnt, bricht es mit einer Fehlermeldung ab, sobald es auf einen Umlaut trifft. Das sind halt diese seltsamen Kodierungen erst das Zeichen, nachträglich zwei Punkte drauf, die außer dem Dateisystem von OSX niemand verwendet. Mittlerweile habe ich es mit PHP umgesetzt, da funktioniert es. Aber bisher nur für 7 Zeichen, ich wäre weiterhin an der richtigen Lösung interessiert.

test.sh:
#!/bin/bash
echo Test > aaäöüÄÖÜß
ls aa*>test.txt
iconv -f UTF-8 -t L1 test.txt
exit

Aufruf:
$ test.sh
aaa
iconv: test.txt:1:3: cannot convert
 
Doch, das klappt. Gut, du musst wissen, welches encoding das OS X filesystem hat ... ;) Aber kuckst du hier:

Code:
SevenOfNine:skl - ~/test
>locale
LANG="de_DE.UTF-8"
LC_COLLATE="de_DE.UTF-8"
LC_CTYPE="de_DE.UTF-8"
LC_MESSAGES="de_DE.UTF-8"
LC_MONETARY="de_DE.UTF-8"
LC_NUMERIC="de_DE.UTF-8"
LC_TIME="de_DE.UTF-8"
LC_ALL=
SevenOfNine:skl - ~/test
>touch "Öle über Hafendächer gießen"
SevenOfNine:skl - ~/test
>ll -1
Öle über Hafendächer gießen
SevenOfNine:skl - ~/test
>ll -1 > liste.txt
SevenOfNine:skl - ~/test
>cat liste.txt
Öle über Hafendächer gießen
liste.txt
SevenOfNine:skl - ~/test
>iconv -f utf-8-mac -t iso-8859-1 liste.txt > latin1.txt
SevenOfNine:skl - ~/test
>cat latin1.txt
?le ?ber Hafend?cher gie?en
liste.txt
 
  • Gefällt mir
Reaktionen: gantim
Noch ein Tipp: Damit TextEdit Latin-1 enkodierte Dokumente korrekt anzeigen kann, muss in den Einstellungen unter Öffnen und Sichern die Codierung hinzugefügt werden.
 
Kann jemand mal testen ob es auch auf einem aktuellen OSX funktioniert? Ich habe hier 10.6.8 ...

Speichern als makem3u.sh

Aufruf zum Debuggen beispielsweise mit
bash -x makem3u.sh .

Es erstellt im angegebenen Verzeichnis M3U-Playlists der Verzeichnisse, die unterhalb des angegebenen Verzeichnisses sind. Wobei die Playlists dann für Latin-1 sein sollten.

Ist ja schon etwas seltsam, dass dieser Player m3u-Dateien wirklich nur in seinem Rootdir zu mögen scheint, aber so sei es ... ;)

Code:
#!/bin/bash
# For Mac OS X 10.6 and AGPTek A02 by tag@gmx.com 2016
# Works fine on Android rooted with BusyBox
# Should work on linux using UTF8-filesystem
if [ $# -ne 1 ]; then
  echo "usage: rootdir for playlists. May be '.'. Will generate m3u for all subfolders."
  exit 1
fi
INPUTDIR="$1"
filedir=""
OLDIFS="$IFS"
IFS=$'\n'
for filepath in $(find $INPUTDIR -type f \( ! -name '.*' \( -iname '*.mp3' -o -iname '*.ogg' -o -iname '*.wma' -o -iname '*.wav' \) \) -print | sort); do
  IFS="$OLDIFS"
  oldfiledir="$filedir"
  filedir="$(dirname "$filepath")"
  dosfiledir=${filedir//\//\\}
  dosfilelen=${#INPUTDIR}
  dosfiledir=${dosfiledir:dosfilelen}
  dosfiledir=${dosfiledir:1}
  filename="$(basename "$filepath")"
  outfilem3u="$(echo $filedir | awk -F/ '{ print toupper($NF) }').m3u"
  echo $outfilem3u ${filename}

  if [ "$oldfiledir" = "$filedir" ]; then
  echo -n '#'EXTINF:-1,$filename$'\r\n'$dosfiledir\\${filename}$'\r\n' >> "$outfilem3u"
  else
  rm -f "$(echo $filedir | awk -F/ '{ print toupper($NF) }').m3u"
  echo -n $'#EXTM3U\r\n#EXTINF:-1,'$filename$'\r\n'$dosfiledir\\$filename$'\r\n' > "$outfilem3u"
  fi
done
# Correction of charset : player needs Latin 1
# no conversion if iconv does not exist
command -v iconv >/dev/null 2>&1 || exit
case "$OSTYPE" in
  darwin*) find $1 -name "*.m3u" -exec sh -c 'iconv -f utf-8-mac -t L1 "{}" >"{}"' \; ;;
  linux*)  find $1 -name "*.m3u" -exec sh -c 'iconv -f utf-8 -t L1 "{}" >"{}"' \; ;;
# untested! Older linux may not need conversion, newer use UTF-8
esac
exit
 
meine Antwort oben ist unter 10.11 erstellt und getestet.
 
  • Gefällt mir
Reaktionen: gantim
OK, danke für die Auskunft, dann wird es hoffentlich gehen. Und nun verstehe ich was nicht ...
Teste ich das ganze wie bisher auf der externen Festplatte, geht alles. Teste ich unter meinem $HOME, dann erzeugt iconv 0-Byte-Dateien! Stimm was mit dem Kommando nicht? Warum geht es nicht überall?
find . -name '*.m3u' -exec sh -x -c 'iconv -f utf-8-mac -t L1 "{}" >"{}"' ';'

(Achtung, das sucht alle *.m3u unterhalb des aktuellen Verzeichnis und macht sie ggf. kaputt!)
 
iconv kann nicht in die selbe Datei schreiben, aus der es liest. (Probiere es mit einer Datei aus).
Ein
Code:
find . -name '*.m3u' -exec sh -x -c 'iconv -f utf-8-mac -t L1 "{}" >"/ziel/pfad/{}"' ';'
funktioniert. Das gibt dann aber Probleme mit Subdirectories, wenn die nicht schon unter /ziel/pfad/ existieren.
Oder Du nimmst
Code:
find . -name '*.m3u' -execdir sh -x -c 'iconv -f utf-8-mac -t L1 "{}" >"/ziel/pfad/{}"' ';'
Dann liegen alle Dateien unter /ziel/pfad/, ohne Subdirectories.
 
  • Gefällt mir
Reaktionen: gantim
Es hat bisher immer funktioniert! Ich dachte, das Flag -o geht nicht, aber per Ausgabeumleitung klappt es. Aber das hängt wohl vom Dateisystem ab. Auf den externen Volumes kein Problem, nur mit der internen Platte nicht. Die Idee hatte ich auch schon und wieder verworfen - weil es bisher zuverlässig ging. Danke für den Tipp in die richtige Richtung! Ich werde es irgendwie umbenennen mit TMP-Name oder so.
 
Zurück
Oben Unten