
Die Quelldatei hat am Anfang jeder Zeile ein Sonderzeichen. Die Datei ist durch doppelte Leerzeichen getrennt.
Beispieldatendatei:
âNAME ABC
âAGE 21
âADDRESS XYZ street ABC city
âCONTACT 13244235
âDOJ 20181212
Ich möchte â
das erste Sonderzeichen in jeder Zeile entfernen und die Datei in eine durch ;
(Semikolon) getrennte Datei konvertieren.
Den folgenden Code habe ich geschrieben, der in UAT einwandfrei funktioniert, in PROD jedoch nicht:
awk '{ print substr($0,1) }' FILE1.txt | sed 's/ /;/' > FILE2.txt
UAT-Ausgabe (erwünschte Ausgabe, die erwartet wird):
NAME;ABC
AGE;21
ADDRESS;XYZ street ABC city
CONTACT;13244235
DOJ;20181212
PROD-Ausgabe:
âNAME;ABC
âAGE;21
âADDRESS;XYZ street ABC city
âCONTACT;13244235
âDOJ;20181212
Derselbe Code funktioniert in UAT einwandfrei, d. h. das Entfernen des ersten Zeichens und die Konvertierung der Datei in eine durch ;
Semikolon getrennte Datei. In PROD wird jedoch nicht das erste Sonderzeichen entfernt, sondern die Datei in eine durch Semikolon getrennte Datei konvertiert.
Ausgabe von locale
:
locale
LANG=en_US.UTF-8
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=
Kann mir hier jemand weiterhelfen...?
Antwort1
Ich denke, dass Ihr Problem möglicherweise mit der Zeichenkodierung zusammenhängt. Versuchen Sie, die FILE1.txt
in beiden Umgebungen anzuzeigen mit
hexdump -C FILE1.txt
Es kann als E-ASCII oder UTF-8 kodiert werden (siehehttps://en.wikipedia.org/wiki/%C3%82#Character_mappings)
Um Ihr Problem zu lösen, können Sie versuchen, beide Kodierungen anzupassen:
â in UTF-8 â in other encoding
| |
v v
sed 's/\xc3\xa2//' FILE1.txt | sed 's/\xE2//' > FILE2.txt
Eine andere Lösung könnte darin bestehen, Ihre Datei vor der Verarbeitung in eine bekannte Kodierung zu konvertieren.
Es kann gefährlich sein, die PROD-Kodierung nicht zu testen.
Antwort2
Da es sich bei dem â
angezeigten Fehler mit ziemlicher Sicherheit um ein Kodierungsproblem handelt und vorausgesetzt wird, dass alle Ihre Zeilen mit einem Großbuchstaben beginnen sollen, können Sie Folgendes versuchen:
LC_ALL=C sed 's/^[^A-Z]*//; s/ */;/g' FILE1.txt > FILE2
Dadurch wird der Befehl mit dem Gebietsschema ausgeführt C
, das sicherstellen sollte, dass das Zeichen, das Sie â
verwenden, nicht im AZ-Bereich enthalten ist. Anschließend entfernt der sed-Befehl einfach alle Zeichen, die nicht im AZ-Bereich liegen, vom Anfang jeder Zeile und konvertiert dann alle Vorkommen von zwei oder mehr Leerzeichen in ;
.
Antwort3
versuchen
sed 's/^â//; s/ */;/g' FILE1.txt > FILE2.txt
Und stimmen Sie ab, wenn es für Sie nicht funktioniert
Antwort4
Um das erste Zeichen jeder Zeile zu entfernen, sollte es lauten:
cut -c2- # not with the GNU implementation which is currently not multi-byte aware
sed 's/^.//'
awk '{print substr($0, 2)}' # note the 2 instead of 1 as offsets are 1-based
# not with mawk or other non-multi-byte aware awk
# implementations.
Beachten Sie jedoch, dass für .
die Übereinstimmung mit diesem â
Zeichen und substr()
für die ordnungsgemäße Funktion dies â
gemäß der Kodierung des Gebietsschemas kodiert werden muss (siehe Ausgabe von locale charmap
).
Um das erste Zeichen zu entfernen und alle Leerzeichenfolgen durch zu ersetzen ;
, haben Sie folgende Möglichkeiten:
sed 's/^.//;s/[[:space:]]\{1,\}/;/g'
Oder:
awk -v OFS=';' '{$0 = substr($0, 2); $1 = $1; print}'
(Beachten Sie jedoch, dass bei Letzterem kein Zeilenende eingefügt wird, ;
das mit einem Leerzeichen endet. Außerdem hängt die Liste der als Trennzeichen betrachteten Leerzeichen von der awk
Implementierung und dem Gebietsschema ab.)
Beachten Sie jetzt auch, dass â
(U+00E2) im Zeichensatz iso8859-1 (auch bekannt als latin1
und in einigen anderen Einzelbyte-Zeichensätzen) als Byte 0xe2 codiert ist. Und dieses Byte 0xe2 ist zufällig auch das erste Byte der Codierung einer Reihe von 3-Byte-UTF-8-Zeichen, darunter mehrere Unicode-Leerzeichen (wie die Leerzeichen U+2000 bis U+200B).
Wenn Sie also eine Anzeige in einem Latin1-Terminal sehen â
, könnte es sein, dass die Eingabe tatsächlich U+2002 (EN SPACE) enthält, beispielsweise codiert in UTF-8 (0xe2 0x80 0x82), und Ihr Terminal würde dies 0xe2
so anzeigen â
und für 0x80 und 0x82, die nicht in Latin1 sind, nichts anzeigen.
Um dieses EN-Leerzeichen zu entfernen, müssen Sie entweder 1 Zeichen aus einem UTF-8-Gebietsschema entfernen oder 3 Zeichen aus einem Einzelbyte-Gebietsschema (z. B. einem mit Latin1 oder dem C-Gebietsschema).