Ich möchte das erste Zeichen aus jeder Zeile als Sonderzeichen entfernen und die Datei in eine durch Semikolon getrennte Datei konvertieren.

Ich möchte das erste Zeichen aus jeder Zeile als Sonderzeichen entfernen und die Datei in eine durch Semikolon getrennte Datei konvertieren.

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.txtin 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 awkImplementierung und dem Gebietsschema ab.)

Beachten Sie jetzt auch, dass â(U+00E2) im Zeichensatz iso8859-1 (auch bekannt als latin1und 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 0xe2so 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).

verwandte Informationen