Habe ich gerade einen Awk-Fehler gefunden?

374
xpt

Mit test2.txt

$ cat /tmp/test2.txt | hexdump -C 00000000 47 61 6c 6c 6f 20 63 65 6c 74 69 63 6f 0a 47 65 |Gallo celtico.Ge| 00000010 73 97 20 42 61 6d 62 69 6e 6f 0a |s. Bambino.| 

Folgendes ist passiert mit awk:

$ cat /tmp/test2.txt | awk '/\x97/' Ges Bambino  $ cat /tmp/test2.txt | awk '/[\x7F-\xFF]/; 1' Gallo celtico Ges Bambino 

Dh die Zeile Ges Bambinoenthält ein Zeichen \x97und awkbestätigt dies im ersten Befehl. Ist \x97aber im Bereich von \x7F-\xFFso sollte die Zeile im zweiten Befehl übersprungen werden, war es aber nicht.

Das sieht awkfür mich wirklich nach einem Fehler aus.
Irgendwelche Kommentare?

PS. um es deutlicher zu machen:

$ cat /tmp/test2.txt | awk '/\x97/; 1' Gallo celtico  $ cat /tmp/test2.txt | awk '/[\x97]/; 1' Gallo celtico Ges Bambino 

AKTUALISIEREN:

@KamilMaciorowski wies darauf hin, dass er lokal verwandt ist. Dh das obige passiert wenn unter

$ set | egrep '^LANG|^LC' LANG=zh_CN.UTF-8 

während beide

cat /tmp/test2.txt | LC_ALL=C awk '/[\x97]/; 1' cat /tmp/test2.txt | LC_ALL=C awk '/[\x7F-\xFF]/; 1' 

geben korrekte Ergebnisse.

Trotzdem ist das ein Problem, oder?

0
Ist es dasselbe, wenn Sie `LC_ALL = C awk…` ausführen? Auch [Sie brauchen "Katze" hier nicht] (https://en.wikipedia.org/wiki/Cat_ (Unix) #Useless_use_of_cat), denke ich. Kamil Maciorowski vor 6 Jahren 0
Ich kann das Problem nicht replizieren. Es kann sich auf Ihr Gebietsschema beziehen. Was ist die Ausgabe von `set | egrep '^ LANG | ^ LC' '? Kamil Maciorowski vor 6 Jahren 0
@ KamilMaciorowski: Ein echter Anhänger der Unix-Philosophie würde stattdessen einen für die Verwendung von Pipes loben, nein? grawity vor 6 Jahren 0
@ KamilMaciorowski, in der Tat ist es mit dem Gebietsschema verbunden. OP aktualisiert xpt vor 6 Jahren 0

1 Antwort auf die Frage

2
grawity

Bytes und Zeichen sind nur im Standardgebiet C("aka" POSIX) identisch, in allen anderen Gebietsschemas sind sie jedoch unterschiedlich. Wenn Ihr System also standardmäßig ein UTF-8-Gebietsschema verwendet (z. B. en_US.UTF-8), dann basieren die "Zeichenklassen" in gawk-Regex auf Zeichen und nicht auf einzelnen Bytes.

Beispielsweise /[eęė]/entspricht dies der /[e\xC4\x99\xC4\x97]/Annahme einer * .UTF-8-Ländereinstellung. wird es jedoch den Brief passen, ęaber nicht č, obwohl beide einen mit C4Byte. (Aus irgendeinem Grund ist dies unterscheidet sich von einer Ebene /\xC4/ außerhalb einer Zeichenklasse, die tut die wörtliche Byte übereinstimmen C4.)

Das Gleiche gilt für Bereiche innerhalb von Zeichenklassen. Da Byte FFkeine gültige UTF-8-Sequenz erstellt, kann die Regex-Bibliothek den gesamten Bereich für ungültig erklären.

gawk hat die -b, --characters-as-bytesOption diese zu deaktivieren.