• Willkommen im Linux Club - dem deutschsprachigen Supportforum für GNU/Linux. Registriere dich kostenlos, um alle Inhalte zu sehen und Fragen zu stellen.

Massenverarbeitung: Zeichenkodierung von Textdatein ändern.

Hallo zusammen.
Ich habe eine Menge einfacher Text-Datein vor mir. Diese sind leider alle mit unterschiedlichen Zeichenkodierungen (ISO-8859-1/2/9; UTF-8; UTF-16) abgespeichert worden. Gibt es auf der Konsole eine Möglichkeit die Zeichenkodierung der Textdatein auszulesen und danach die Zeichenkodierung zu verändern?
(In den ganzen Datein, sind keine Fremdspachrigen-Zeichen enthalten)

Mein Ziel ist es ein Script/Befehl zu schreiben, der die Massen an Datein automatisch ändert.
Hat jemand eine Idee? Beziehungsweise ein Ideenansatz?
 
Schleife mit find und iconv - iconv ist allerdings manchmal ein wenig unglücklich in der Konvertierung, diesbezüglich haben wir bei uns eine kleine Java-Klasse geschrieben, die das besser kann...
 
Kann iconv automatisch erkenn welche Kodierung verwendet wurde? Also kann ich bei iconf einfach auch "-f" weglassen?
 
Auch
Code:
recode latin1..utf8 file.txt
Die Zeichenkodierung zuvor prüfen müßtest Du allerdings selbst noch.
Das heißt, wenn's kein latin1 ist, wird's trotzdem (zu Müll) umgewandelt.
 
Ok. Ich versuche es mal mit "file" und "iconv" (Falls ich merke, dass iconv nicht sauber arbeitet, kann man ja auch noch recode versuchen bzw. einfach im Script ersetzen)

Ich bin jetzt nicht der Shell-Guru. Würde mal mit folgenden Befehlen anfangen:
Code:
eingabedatei=$1
zeichensatz = file -i 'TEXTDATEI' | cut -f1 -d '='
iconv -f $zeichensatz -t UTF-8 $eingabedatei
Würde das passen? Wenn ja, wie kann man das auf ein ganzes Verzeichnis anwenden, bzw. auch noch rekursiv? Irgendwas mit while...do? Weiß da jemand bescheid?
 
A

Anonymous

Gast
MatzUp schrieb:
Ich bin jetzt nicht der Shell-Guru. Würde mal mit folgenden Befehlen anfangen:
Code:
eingabedatei=$1
zeichensatz = file -i 'TEXTDATEI' | cut -f1 -d '='
iconv -f $zeichensatz -t UTF-8 $eingabedatei
Würde das passen?

Wenn du das mit Konsole machen willst, musst du dir erst mal überlegen mit welcher Shell du das abarbeiten lassen willst. Standard ist bash.
Die Zeilen dort oben ist zumindestens schon mal kein bash kein csh und nichts anderes mir bekanntes.
Code:
> bash DeineZeilen.sh test1.txt
DeineZeilen.sh: Zeile 2: zeichensatz: Kommando nicht gefunden.
iconv: Konvertierung von »-t« wird nicht unterstützt
»iconv --help« oder »iconv --usage« gibt weitere Informationen.

>  csh DeineZeilen.sh test1.txt
eingabedatei=test1.txt: Befehl nicht gefunden.
zeichensatz: Befehl nicht gefunden.
zeichensatz: Undefinierte Variable.
Wir helfen ja gerne, aber ein bisschen mehr musst du dich da schon anstrengen.


Zum 2 . wirst du auf folgendes Problem stoßen, das dir file (übrigends durchaus auch stark versionsabhängig) Mist erzählt und zwar bei Testdateien ne ganze Menge Mist, dass man die Ausgaben insbesondere bei Textdateien eventuell als Hilfe nutzen könnte, aber nicht so ernst nehmen sollte. Somit sollte das keine allzugute Idee sein, dass gleich an seine originalen Dateien auszuprobieren. Die Ergebnisse nach iconv sehen nicht selten so hier aus. ;)
Code:
> cat test*.txt
Das ist eine überaus schöne Scheißdatei
Das ist eine ÃŒberaus schöne ScheiÃdatei
Das ist eine 眉beraus sch枚ne Schei脽datei
Das ist eine überaus schöne ScheiÃdatei
Das ist eine Ăźberaus schĂśne ScheiĂdatei

> file -i test*.txt
test.txt:  text/plain; charset=utf-8
test1.txt: text/plain; charset=utf-8
test2.txt: text/plain; charset=utf-8
test3.txt: text/plain; charset=utf-8
test4.txt: text/plain; charset=utf-8

robi
 
MatzUp schrieb:
Kann iconv automatisch erkenn welche Kodierung verwendet wurde? Also kann ich bei iconf einfach auch "-f" weglassen?
Nein.
Das Problem ist dass die vielen verschiedenen Encodings nicht eindeutig sind. Eine Datei mit dem inhalt
Code:
Hello World
ist sowohl valides ASCII als auch Latin1 oder UTF-8
 
Sehe ich das also richtig. Das man eigentlich gar nicht wirklich die Zeichenkodierung herausfinden kann, bzw. die herausgefundene auch falsch sein kann?

Ich habe inzwischen dennoch an dem Script weitergearbeitet und das sollte zumindest für einzelne Dateien funktionieren:
Code:
#!/bin/bash
##GPLv3
[[ $# -ne 1 ]] && echo -e "### Need a file. \n### Usage: 'convert-characters.sh PATH/FILE' \n### Abort..." && exit 10
inputfile=$1
echo "This list of files need to be proofed, because of unexpectet character set." > ~/proof-list-of-files.txt

chracaterset=$(file -i ${inputfile}  | cut -d '=' -f2)
 if [[ ${chracaterset} =  "iso-8859-1" || ${chracaterset} = "iso-8859-15" || ${chracaterset} = "iso-8859-2" ]]
 then
  echo "The file '${inputfile}' has the follwoing chracater set: ${chracaterset}"
  iconv -f ${chracaterset} -t UTF-8 ${inputfile} -o coverted/${inputfile}
  echo "Ok. '${inputfile}' is now converted."
 else
  echo "This file ${inputfile} is now set in the list, who need to be proofed after exit." | tee -a ~/proof-list-of-files.txt
  iconv -f iso-8859-1 -t UTF-8 ${inputfile} -o coverted/${inputfile}
  echo "Ok. '${inputfile}' is now converted."
 fi
echo "### ### ### ###"
echo -e "## I've created a textfile in '~/proof-list-of-files.txt'. \n## It will list files who need to be proofed, because of unexpectet charter set."
echo "## Each new converted file is stored in the subfolder 'converted'."
echo "### ### ### ###"
exit 0
Der Code konvertiert die Eingabedatei auf UTF-8. Falls die Eingabedatei durch "file -i" eine anderen Zeichensatz als den erwarteten aufweist, wird diese Eingabedatei dennoch konvertiert, jedoch mit dem Hinweis diese nochmals speziell zu überprüfen.

Wobei ich jedoch noch Hilfe bräuchte, wäre wie zuvor erwähnt, wie man das script rekursiv auf Verzeichnisse anwenden kann. Inzwischen weiß ich auch, dass ich "find" verwenden muss. Was ich jedoch nicht weiß ist, wie ich mit der jeweiligen gefundene Datei den kompletten Code ausführen lassen kann.
 
Vielen Dank dafür. Jedoch gibt es noch ein Problem. Wo die Dateinamen Leerzeilen enthalten wird jeder einzelner Dateinamen-Abschnitt für sich behandelt.
Z.b. erscheint die Datei: "Das ist eine Test.txt" durch das Kommando find, wie 4 einzelne zu bearbeitende Dateien: "Das"; "ist"; "eine"; "Testdatei.txt"

Code:
#!/bin/bash
##GPLv3
[[ $# -ne 1 ]] && echo -e "### Need a path. \n### Usage: 'convert-characters.sh PATH' \n### abort" && exit 10
inputpath=$1
echo "This list of files need to be proofed, because of unexpectet character set." > ~/proof-list-of-files.txt
for inputfile in $(find ${inputpath} -type f -name "*.txt")
do
chracaterset=$(file -i ${inputfile}  | cut -d '=' -f2)
 if [[ ${chracaterset} =  "iso-8859-1" || ${chracaterset} = "iso-8859-15" || ${chracaterset} = "iso-8859-2" ]]
 then
  echo "The file '${inputfile}' has the follwoing chracater set: ${chracaterset}"
#  iconv -f ${chracaterset} -t UTF-8 ${inputfile} -o coverted/${inputfile}
  echo "Ok. '${inputfile}' is now converted."
 else
  echo "${inputfile}" >> ~/proof-list-of-files.txt
  echo "This file ${inputfile} is now set in the list, who need to be proofed after exit."
#  iconv -f iso-8859-1 -t UTF-8 ${inputfile} -o coverted/${inputfile}
  echo "Ok. '${inputfile}' is now converted."
 fi
done
echo "### ### ### ###"
echo -e "## I've created a textfile in '~/proof-list-of-files.txt'. \n## It will list files who need to be proofed, because of unexpectet charter set."
echo "## Each new converted file is stored in the subfolder 'converted'."
echo "### ### ### ###"
exit 0
 
MatzUp schrieb:
Vielen Dank dafür. Jedoch gibt es noch ein Problem. Wo die Dateinamen Leerzeilen enthalten wird jeder einzelner Dateinamen-Abschnitt für sich behandelt.
Altes Shell-Problem. Statt der von marce vorgeschlagenen Konstruktion nimm lieber:
Code:
find /wo -name "*was*" -type f | while read inputfile 
do
  $something
done
Und setze $inputfile im folgenden immer in "". Sonst bekommst Du die Leerzeichen nicht mit.
 
Thanks. Damit klappt es:

Code:
#!/bin/bash
##GPLv3
[[ $# -ne 1 ]] && echo -e "### Need a path. \n### Usage: 'convert-characters.sh PATH' \n### abort" && exit 10
inputpath=$1
echo -e "This list of files need to be proofed, because of unexpectet character set. \n \n" > ~/proof-list-of-files.txt
find ${inputpath} -name "*.txt" -type f | while read inputfile
do
chracaterset=$(file -i "${inputfile}"  | cut -d '=' -f2)
 if [[ ${chracaterset} =  "iso-8859-1" || ${chracaterset} = "iso-8859-15" || ${chracaterset} = "iso-8859-2" ]]
 then
  echo "The file '"${inputfile}"' has the follwoing chracater set: ${chracaterset}"
  iconv -f ${chracaterset} -t UTF-8 "${inputfile}" -o coverted/"${inputfile}"
  echo "Ok. '"${inputfile}"' is now converted."
 else
  echo ""${inputfile}"" >> ~/proof-list-of-files.txt
  echo -e "--> $(file -i "${inputfile}" | cut -d '=' -f2) \n" >> ~/proof-list-of-files.txt
  echo "This file "${inputfile}" is now set in the list, which need to be proofed after exit."
  iconv -f iso-8859-1 -t UTF-8 "${inputfile}" -o coverted/"${inputfile}"
  echo "Ok. '"${inputfile}"' is now converted."
 fi
done
echo "### ### ### ###"
echo -e "## I've created a textfile in '~/proof-list-of-files.txt'. \n## It will list files who need to be proofed, because of unexpectet charter set."
echo "## Each new converted file is stored in the subfolder 'converted'."
echo "### ### ### ###"
exit 0
 
Oben