[gelöst] awk: Kommazahl -> Uhrzeit - locale Problem?

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
Benutzeravatar
detix
Beiträge: 1699
Registriert: 07.02.2007 18:51:28
Wohnort: MK

[gelöst] awk: Kommazahl -> Uhrzeit - locale Problem?

Beitrag von detix » 13.02.2021 13:12:02

Für die Umrechnung einer Kommazahl in eine Uhrzeit nutze ich awk:

Code: Alles auswählen

awk '{printf "%02d:%02d\n", $0, ($0 * 60 % 60)}' <<<3.212121
03:12 # ok
awk '{printf "%02d:%02d\n", $0, ($0 * 60 % 60)}' <<<3,212121
03:00 # falsch
so funktioniert es unter buster, bei bullseye und sid ist es genau umgekehrt:

Code: Alles auswählen

awk '{printf "%02d:%02d\n", $0, ($0 * 60 % 60)}' <<<3.212121
03:00 # falsch
awk '{printf "%02d:%02d\n", $0, ($0 * 60 % 60)}' <<<3,212121
03:12 # ok
Die lokalen Einstellungen sind alle völlig gleich:

Code: Alles auswählen

locale
LANG=de_DE.UTF-8
LANGUAGE=de
LC_CTYPE="de_DE.UTF-8"
LC_NUMERIC="de_DE.UTF-8"
...
für bullseye und sid muss ich in einem Skript genauso wie in einer Konsole zuerst noch die LC_NUMERIC (C oder Anderes) neusetzen, intern will awk überall den Punkt als Trennzeichen haben, von außen nur das Komma.
Kann mir das mal jemand erklären?
Zuletzt geändert von detix am 13.02.2021 15:57:25, insgesamt 1-mal geändert.
Gruß an alle Debianer, und immer daran denken:
Macht ohne Haftung funktioniert nicht!

JTH
Moderator
Beiträge: 3014
Registriert: 13.08.2008 17:01:41
Wohnort: Berlin

Re: awk: Kommazahl -> Uhrzeit - locale Problem?

Beitrag von JTH » 13.02.2021 13:52:48

Hast du evtl. verschiedene awk-Implementierungen installiert? Debiangawk, Debianmawk, Debianoriginal-awk verhalten sich anscheinend unterschiedlich, hier unter Sid:

Code: Alles auswählen

user@host:~$ awk '{printf "%02d:%02d\n", $0, ($0 * 60 % 60)}' <<<3.212121
03:12
user@host:~$ awk '{printf "%02d:%02d\n", $0, ($0 * 60 % 60)}' <<<3,212121
03:00
user@host:~$ mawk '{printf "%02d:%02d\n", $0, ($0 * 60 % 60)}' <<<3,212121
03:12
user@host:~$ gawk '{printf "%02d:%02d\n", $0, ($0 * 60 % 60)}' <<<3,212121
03:00

Code: Alles auswählen

user@host:~$ ls -l /bin/awk /etc/alternatives/awk
lrwxrwxrwx 1 root root 21 Oct 28  2018 /bin/awk -> /etc/alternatives/awk
lrwxrwxrwx 1 root root 13 Oct 29  2018 /etc/alternatives/awk -> /usr/bin/gawk

Code: Alles auswählen

user@host:~$ locale
LANG=en_DK.UTF-8
LANGUAGE=en_US:en
LC_CTYPE="en_DK.UTF-8"
LC_NUMERIC="en_DK.UTF-8"
[…]

Debianmawk ist required, in einer Neuinstallation also vorhanden. Debiangawk nur wenn von Hand nachinstalliert. gawk hat in den Alternatives allerdings die höhere Priorität, wird also normalerweise als /bin/awk verlinkt, wenn installiert:

Code: Alles auswählen

$ update-alternatives --display awk
[…]
/usr/bin/gawk - priority 10
  […]
/usr/bin/mawk - priority 5
  […]
Manchmal bekannt als Just (another) Terminal Hacker.

Benutzeravatar
detix
Beiträge: 1699
Registriert: 07.02.2007 18:51:28
Wohnort: MK

Re: awk: Kommazahl -> Uhrzeit - locale Problem?

Beitrag von detix » 13.02.2021 15:56:41

Genau das ist es!
Auf allen Systemen:

Code: Alles auswählen

apt-mark showmanual | grep awk
mawk
und nur bei buster gibt es eine Ausgabe für:

Code: Alles auswählen

apt-mark showauto | grep awk
gawk

update-alternatives --display awk
awk - automatischer Modus
  beste Version des Links ist /usr/bin/gawk
Dann muss ich gawk wohl mal von Hand installiert haben, der kleine aber feine Unterschied...
Herzlichen Dank für deine Hilfe JTH, gelöst!
Gruß an alle Debianer, und immer daran denken:
Macht ohne Haftung funktioniert nicht!

Benutzeravatar
Meillo
Moderator
Beiträge: 8782
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: [gelöst] awk: Kommazahl -> Uhrzeit - locale Problem?

Beitrag von Meillo » 13.02.2021 17:46:22

Welche Implementierung beruecksichtigt nun LC_NUMERIC (und damit bei deutschem Locale die Zahl mit dem Komma)?
Use ed once in a while!

Benutzeravatar
detix
Beiträge: 1699
Registriert: 07.02.2007 18:51:28
Wohnort: MK

Re: [gelöst] awk: Kommazahl -> Uhrzeit - locale Problem?

Beitrag von detix » 13.02.2021 18:21:50

mawk bei bullseye und sid hätte gern das Komma, mawk und gawk bei buster den Punkt.
bullseye und sid:

Code: Alles auswählen

LC_NUMERIC=C mawk '{printf "%02d:%02d\n", $0, ($0 * 60 % 60)}' <<<7.78216
07:46
kleiner Nachtrag: es geht nur um den einzulesenden Wert...
Gruß an alle Debianer, und immer daran denken:
Macht ohne Haftung funktioniert nicht!

Benutzeravatar
Meillo
Moderator
Beiträge: 8782
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: [gelöst] awk: Kommazahl -> Uhrzeit - locale Problem?

Beitrag von Meillo » 13.02.2021 18:59:47

detix hat geschrieben: ↑ zum Beitrag ↑
13.02.2021 18:21:50
mawk bei bullseye und sid hätte gern das Komma, mawk und gawk bei buster den Punkt.
D.h. mit dem Wechsel von Version 1.3.3 (in Buster) auf 1.3.4 (in Bullseye) beruecksichtigt mawk LC_NUMERIC.

Bei gawk 4.2.1 (in Buster) wird LC_NUMERIC ignoriert. Wie sieht es bei gawk 5.1.0 (in Bullseye) aus?

bullseye und sid:

Code: Alles auswählen

LC_NUMERIC=C mawk '{printf "%02d:%02d\n", $0, ($0 * 60 % 60)}' <<<7.78216
07:46
kleiner Nachtrag: es geht nur um den einzulesenden Wert...
Wenn du LC_NUMERIC=C setzt, dann hast du immer ein definiertes Verhalten (egal ob LC_NUMERIC beruecksichtigt oder ignoriert wird): der Punkt ist dann der Dezimaltrenner.


Das ist was POSIX dazu sagt:
https://pubs.opengroup.org/onlinepubs/9699919799/utilities/awk.html hat geschrieben: LC_NUMERIC
Determine the radix character used when interpreting numeric input,
performing conversions between numeric and string values, and formatting
numeric output. Regardless of locale, the <period> character (the
decimal-point character of the POSIX locale) is the decimal-point character
recognized in processing awk programs (including assignments in command
line arguments).

Wenn ich das richtig verstehe, muss es so aussehen:

Code: Alles auswählen

echo "8,17" | LC_NUMERIC=de_DE.UTF-8 awk -v pi=3.141592 '{ f=1.01; s="2,34"; print $0+0, pi, f, s+0 }'
(Code inkl. Variablenzuweisungen auf der Kommandozeile mit Dezimalpunkt. Externer Input und String-to-Float-Konvertierungen mit dem Dezimaltrenner des Locales.)


Koennte das jemand mit mawk unter Bullseye testen? (Gerne zusaetzlich mit gawk.)
Use ed once in a while!

Benutzeravatar
detix
Beiträge: 1699
Registriert: 07.02.2007 18:51:28
Wohnort: MK

Re: [gelöst] awk: Kommazahl -> Uhrzeit - locale Problem?

Beitrag von detix » 13.02.2021 19:47:31

Sehr gern, bullseye mit frisch installiertem gawk:

Code: Alles auswählen

echo "8,17" | LC_NUMERIC=de_DE.UTF-8 mawk -v pi=3.141592 '{ f=1.01; s="2,34"; print $0+0, pi, f, s+0 }'
8,17 3.141592 1,01 2,34

echo "8,17" | LC_NUMERIC=de_DE.UTF-8 gawk -v pi=3.141592 '{ f=1.01; s="2,34"; print $0+0, pi, f, s+0 }'
8 3.141592 1.01 2
Gruß an alle Debianer, und immer daran denken:
Macht ohne Haftung funktioniert nicht!

Benutzeravatar
Meillo
Moderator
Beiträge: 8782
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: [gelöst] awk: Kommazahl -> Uhrzeit - locale Problem?

Beitrag von Meillo » 13.02.2021 20:01:03

detix hat geschrieben: ↑ zum Beitrag ↑
13.02.2021 19:47:31
Sehr gern, bullseye mit frisch installiertem gawk:

Code: Alles auswählen

echo "8,17" | LC_NUMERIC=de_DE.UTF-8 mawk -v pi=3.141592 '{ f=1.01; s="2,34"; print $0+0, pi, f, s+0 }'
8,17 3.141592 1,01 2,34

echo "8,17" | LC_NUMERIC=de_DE.UTF-8 gawk -v pi=3.141592 '{ f=1.01; s="2,34"; print $0+0, pi, f, s+0 }'
8 3.141592 1.01 2
Vielen Dank! :THX:

mawk tut hier wie es nach POSIX beschrieben ist. Dass `pi' mit einem DezimalPUNKT ausgegeben wird liegt daran, dass intern nie eine Konvertierung in eine Zahl stattfindet, sondern es durchweg ein String ist. (Ich haette bei der Ausgabe hinter jede Variable ein `+0' setzen sollen, um sicherzustellen, dass eine Konvertierung in eine Zahl geschieht.)

gawk ignoriert also (auch in Version 5.1.0 noch) LC_NUMERIC und verhaelt sich diesbezueglich *nicht* POSIX-kompatibel. Ich glaube zwar nicht, dass es etwas aendert, aber teste es bei Gelegenheit mal noch mit der Option `--posix' bei gawk.


Spannende Sache. :-) Danke, detix, fuer den Thread!
Use ed once in a while!

JTH
Moderator
Beiträge: 3014
Registriert: 13.08.2008 17:01:41
Wohnort: Berlin

Re: [gelöst] awk: Kommazahl -> Uhrzeit - locale Problem?

Beitrag von JTH » 14.02.2021 00:08:24

Dacht ichs mir doch, dass das Thema noch einen gewissen Leser findet ;)

Meillo hat geschrieben: ↑ zum Beitrag ↑
13.02.2021 20:01:03
gawk ignoriert also (auch in Version 5.1.0 noch) LC_NUMERIC und verhaelt sich diesbezueglich *nicht* POSIX-kompatibel. Ich glaube zwar nicht, dass es etwas aendert, aber teste es bei Gelegenheit mal noch mit der Option `--posix' bei gawk.
Die GNU-Werkzeuge haben ja gerne mal ihre eigene, laxe Umsetzung von Posix, außer man zwingt sie, strinkt zu sein.

Der manpage nach sollte --posix das Verhalten von gawk schon dem von mawk angleichen (Nachtrag: tut es). Daneben gäbe es noch --use-lc-numeric, was nur diesen einen Punkt anpasst:
man gawk hat geschrieben: --use-lc-numeric
Force gawk to use the locale's decimal point character when parsing input data. Although the POSIX standard requires this behavior,
and gawk does so when --posix is in effect, the default is to follow traditional behavior and use a period as the decimal point,
even in locales where the period is not the decimal point character. This option overrides the default behavior, without the full
draconian strictness of the --posix option.

Die Umgebungsvariable POSIXLY_CORRECT zu setzen wäre ja noch ne Variante, das Verhalten von beiden *awk anzugleichen, ohne die obigen Schalter zu benutzen, die mawk dann wieder nicht versteht. Wäre dann unabhängig davon, welches nun gerade installiert ist, mawk ignoriert die Variable einfach.
Manchmal bekannt als Just (another) Terminal Hacker.

Benutzeravatar
Meillo
Moderator
Beiträge: 8782
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: [gelöst] awk: Kommazahl -> Uhrzeit - locale Problem?

Beitrag von Meillo » 14.02.2021 08:24:01

Danke, JTH! :THX:

Ich nehme meine Skepsis an gawks POSIX-Kompatibilitaet zurueck.
Use ed once in a while!

Benutzeravatar
detix
Beiträge: 1699
Registriert: 07.02.2007 18:51:28
Wohnort: MK

Re: [gelöst] awk: Kommazahl -> Uhrzeit - locale Problem?

Beitrag von detix » 14.02.2021 09:36:47

Na das ist doch alles wunderbar, jetzt kann ich mich je nach Eingangswert entscheiden:

Punkt: gawk oder mawk (buster), gawk oder mawk mit Setzen von LC_NUMERIC (bullseye)
Komma: gawk mit Parameter -P oder -N (buster und bullseye), mawk funktioniert bei bullseye aber nicht bei buster.

Vielen Dank euch beiden für meine nun komplette Verwirrung... :lol:
Gruß an alle Debianer, und immer daran denken:
Macht ohne Haftung funktioniert nicht!

Antworten