1 hónappal ezelőtt Ubuntu 20.04-en és 18.04-en jelenleg is:
echo "30.1 32.3 0.0 0.0 0.0 16.4" | awk '{for( x=(NF); x>=2; x--) if($x!=0.0) print $x;}'
16.4
32.3
Ez az elvárt működés.
Ugyanaz a parancs Ubuntu 20.04-en jelenleg:
echo "30.1 32.3 0.0 0.0 0.0 16.4" | awk '{for( x=(NF); x>=2; x--) if($x!=0.0) print $x;}'
16.4
0.0
0.0
0.0
32.3
Ez már nem jó, a nullákat nem kéne, hogy kiírja... wtf?
Már nem fut le a scriptem normálisan, ami egy hónapja még működött. Megváltozott az if szintaktikája az awk-ban?
Hozzászólások
awk, mawk vagy gawk fut éppen nálad awk néven?
Nem említettem, mert Ubuntu default:
$ awk -W version
mawk 1.3.4 20200120
$ sudo apt install gawk
és jó lesz.
$ awk --version
GNU Awk 5.0.1, API: 2.0 (GNU MPFR 4.0.2, GNU MP 6.2.0)
Nemtom mi a default, de nalam (Ubuntu 20.04) gawk van (es mukodik jol a fenti), nem hiszem, hogy valaha kezzel alitottam volna ezt. Viszont 18.04-rol update-eltem, lehet, hogy ez szamit.
Tedd idézőjelbe a 0.0-t. Szerintem numerikusan 0-vá konvertálódik az egyik helyen, míg a másikon nem, és ezért. Az awk-ban is vannak típusok, csak nem tűnik fel az automatikus konverzió miatt.
tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE
Még ezt is nézd meg:
tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE
Nekem megy így:
ice@ubuntu:~/.ssh$ cat /etc/issue
Ubuntu 20.04 LTS \n \l
ice@ubuntu:~/.ssh$ echo "30.1 32.3 0.0 0.0 0.0 16.4" | awk '{for( x=(NF); x>=2; x--) if($x != "0.0") print $x;}'
16.4
32.3
Így működik, de egyrészt én numerikus összehasonlítást szeretnék, másrészt meg lehet, hogy 50 másik helyen is megváltozott a program működése? Nem akarom én átírni, meg debugolni, ha eddig jó volt.
Engem az érdekelne, hogy mi változott meg és miért. Na meg, hogy a kód átírása nélkül újra működjön.
$ mawk -W version
mawk 1.3.4 20190203
Copyright 2008-2018,2019, Thomas E. Dickey
Copyright 1991-1996,2014, Michael D. Brennan
random-funcs: arc4random_stir/arc4random
regex-funcs: internal
compiled limits:
sprintf buffer 8192
maximum-integer 2147483647
$ echo $LANG
hu_HU.UTF-8
$ echo "30.1 32.3 0.0 0.0 0.0 16.4" | mawk '{for( x=(NF); x>=2; x--) if($x!=0.0) print $x;}'
16.4
0.0
0.0
0.0
32.3
$ ( LANG=C ; export LANG ; echo "30.1 32.3 0.0 0.0 0.0 16.4" | mawk '{for( x=(NF); x>=2; x--)
16.4
32.3
$
tl;dr
Egy-két mondatban leírnátok, hogy lehet ellopni egy bitcoin-t?
Lokalizacio? Tizedespont helyett tizedesvesszo valamiert? Hasznalj igazi lokalizaciot (LANG=C) minden kritikus dologhoz.
Nálam mind a kettőnél ugyanúgy kiírja a nullákat... :(
Nálam:
Már feljebb írtam, hogy nálam mawk 1.3.4.
A másik gépen, amin jól működik meg: mawk 1.3.3. (Ubuntu 18.04)
( Legalább egy export LANG ; -ot mondj még az echo előtt! És ha nem akarod elbarmolni a környezetedet, akkor az egész sort rakd ( ) közé. Ugyanis baromira shell függő, hogy mi történik egy exportált változóval, ha az export után új értéket kap. )
Amúgy szerintem is lokalizációs gondnak tűnik.
tl;dr
Egy-két mondatban leírnátok, hogy lehet ellopni egy bitcoin-t?
( LANG=C ; export LANG ; echo "30.1 32.3 0.0 0.0 0.0 16.4" | awk '{for( x=(NF); x>=2; x--) if($x!=0.0) print $x;}' )
Így működik.
De eddig működött így is:
$ echo $LANG
hu_HU.UTF-8
És a 18.04-es gépen szintén működik most is. Szóval a rejtély még nincs teljesen megoldva.
Nem lehet, hogy az Ubuntunál rájöttek, hogy Magyarországon tizedesvessző van, nem pedig tizedespont? Aztán jött egy frissítés...
Szerk.: Azt sohasem értettem, amikor megvan a megoldás, és továbbra megy az értetlenkedés, hogy ez pontosan úgy legyen jó, ahogy eddig. Akkor pontosan azt a rendszert használd frissítetlenül, mint amelyikkel jó volt.
tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE
Az lehet, de akkor meg ennek kéne működnie, nem?
$ echo "30,1 32,3 0,0 0,0 0,0 16,4" | awk '{for( x=(NF); x>=2; x--) if($x!=0,0) print $x;}'
awk: line 1: syntax error at or near ,
Elfogadom a változást, ha tényleg ez a megoldás és direkt csinálták, nem regresszió. De mondjuk ha nem major verzió váltásról van szó, akkor csak nem kellene, hogy elromoljon egy script.
OFF:
mióta van, hogy a mawk a default AWK az Ububan? Meg mernék esküdni rá, hogy régebben valamelyik GAWK verziót adták. - Bár a net szerint már 14.04-ben is mawk volt. Amúgy nem lehet, hogy a volt a 20.04-ben awk verzió frissítés ebben az elmúlt egy hónapban?
/OFF
sudo update-alternatives --config awk
Esetleg?
tl;dr
Egy-két mondatban leírnátok, hogy lehet ellopni egy bitcoin-t?
A /var/log/apt/ könyvtárban lévő history logok szerint nem volt awk frissítés mostanában.
Ez januári update. A scriptem május elején még lefutott.
Meg ebben a logban mi utal ilyesmi változtatásra?
Szerintem eleve nem jó a scripted. Nekem ez nem tetszik:
Mert ez numerikus 0, és szerintem implementáció kérdése, hogy a 0, 0.0, 0.00, 0x00, 00 közül mindegyik, vagy csak egyesek felelnek meg az egyenlőségnek. Jó, a 0x00 lehet, hogy csak strtonum() hívását követően lesz nulla. Szóval, ha számként nullát akarnék, akkor 0-t írnék, nem kell bele pont. Ha meg stringként, akkor "0.0" a megoldás. Így mindenképp zavaró.
tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE
Ha 0.0 helyett 0 van, akkor se jó. Ha meg 0.0-át nem szabad odaírni, akkor 16.4-et sem? Mert azzal sem jó.
Meg az x változónak nem szabad felvennie a 0.0 értéket numerikus összehasonlítás előtt?
Erről beszélek:
tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE
A 16.4 egy szám, ami egyenlő 16.4-del, vagy például16.400-del is például. Viszont stringként a "16.4" nem lesz egyenlő "16.400"-zal, mert van ott még két darab '0', azaz 0x30 kódú karakter.
tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE
Én ezt értem, de itt szó sincs stringként való összehasonlításról. Nem értem, hogy kanyarodtunk ide.
Ez az eredeti probléma:
mawk Ubuntu 20.04:
$ awk 'BEGIN { x=12.3; if(x==12.3) printf("true\n"); else printf("false\n");}'
true
$ echo "12.3" | awk '{ if($1==12.3) printf("true\n"); else printf("false\n"); }'
false
mawk Ubuntu 18.04:
$ awk 'BEGIN { x=12.3; if(x==12.3) printf("true\n"); else printf("false\n");}'
true
$ echo "12.3" | awk '{ if($1==12.3) printf("true\n"); else printf("false\n"); }'
true
gawk Ubuntu 20.04:
$ awk 'BEGIN { x=12.3; if(x==12.3) printf("true\n"); else printf("false\n");}'
true
$ echo "12.3" | awk '{ if($1==12.3) printf("true\n"); else printf("false\n"); }'
true
Miért false a második? Illetve ha elfogadjuk, hogy false a második, akkor miért true az első?
Bugos a mawk vagy nem?
Próbáld meg ezt mawk Ubuntu 20.04 környezetben, kíváncsi vagyok az eredményre:
Szerintem true lesz.
tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE
True. :)
Mit csinál az a pipe....? 1 hónapja még nem csinálta? Gawk-nál miért nem probléma most se?
Miközben reggeliztem, majd megcsináltam a fahéjas gyömbér teámat, megértettem a jelenséget. :)
A mawk interpreteren belül a kódra nézvést nincs lokalizáció. Szépen is néznénk ki, ha a környezeti változóktól függene, amit a scriptben leírsz. Tehát ott a 12.3 egy szám, bármi is legyen a lokalizáció. Ezzel szemben az input - és vélelmezem, egy printf("%.2f") esetén az output is, bár nem biztos - feldolgozása a lokalizációs függvények hívásán keresztül történik. Azaz 12,3 egy szám, de más lokalizációval 12.3 egy szám.
Amikor az inputod "0.0" volt, s összehasonlítottad 0.0-val, akkor a magyar lokalizáció szerint ezt nem lehetett számmá konvertálni, így "0.0" string lett belőle. Az összehasonlításkor leírt 0.0 konstans előbb numerikus 0-vá konvertálódott, majd, hogy ne legyen type mismatch, kénytelen lett "0" stringgé konvertálódni. Így a programodban az if("0.0" != "0") hajtódott végre, ami true, s ezért írta végül ki a "0.0"-t.
tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE
Nekem akkor is új, hogy a pipe bármit is változtasson a tartalmon, amit átirányít...
Ugye láttad, hogy az echo paraméterében vessző volt a "tizedespont" ?
(Szóval a pipe semmit nem változtat, de ahogy a kollága írja, valószínűleg a magyar lokalizációval megadott törtet a "valódi" 12.3 -ra átalakítja az input során, ami nyilván megegyezik a 12.3-mal.)
tl;dr
Egy-két mondatban leírnátok, hogy lehet ellopni egy bitcoin-t?
Láttam, azért kérdezem, hogy mióta nyúl bele a pipe a tartalomba... duh.
Olyan nincs, hogy "semmit nem változtat" és "de átalakítja az input során". Vagy ez vagy az. Milyen alapon alakítja át? Nem excel az. Legközelebb a 10.15.2018-at fogja átalakítani 2018-10-15-re?
Ugyanakkor gawk:
$ echo "12,3" | awk '{ if($1==12.3) printf("true\n"); else printf("false\n"); }'
false
Újra kérdezem:
- Ha mawk van, akkor a pipe átalakítja a vesszőt ponttá lokalizáció szerint? Ha gawk van, akkor meg nem. Akkor pont, hogy a ponttal működik. Megnézi a pipe, hogy mi jön utána és aszerint alakítgat? Le van ez valahova írva?
Ha a pipe alakítgatna, akkor ugyanaz lenne a mawk és a gawk működése, nem?
- 1 hónapja még a mawk is működött ponttal. Mi változott?
Az alanyt értetted félre, nem az echo vagy a pipe alakít át bármit is, hanem maga az awk.
A pipe bitre pontosan azt viszi át, amit kell. A mawk az, amelyik a környezeti változótól függően vagy 12.3, vagy 12,3 alakban várja az inputben a tizedes törteket. Ha a lokalizációd szerint tizedesvesszőt vár, miközben tizedesponttal kínálod meg, ezt nem fogja számként értelmezni, hanem azt mondja, akkor ez bizony egy string. Az összehasonlítás másik operandusa egy szám volt. Stringet számmal nem lehet összehasonlítani, a string operandust nem lehet számmá alakítani, így az egyetlen lehetőség, hogy a szám operandust konvertálta stringgé, majd utána végezte el az összehasonlítást. Igen ám, de a "0.0" és a "0" stringek valóban nem azonosak. Már a hosszuk is különbözik. Emiatt teljesült a != feltétel, s írta ki, amit nem szerettél volna.
A gawk szerintem egész egyszerűen nem foglalkozik az inputban a számok lokalizációjával. Ebben az értelemben éppen az mawk a fejlettebb.
A megoldás tehát az, ahogy írtam is, hogy a mawk-t a megfelelő környezeti változó megadását követően hívod meg.
tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE
Nem barmolom el a környezetet, ui. tcsh a default shell és csak azon belül indítottam egy sh-t.
Csak megerositeskeppen, GNU Awk hasznalataval az elso peldadban szereplo modon megy, minden Linuxomon az van (megneztem), de meg FBSD-n is ezt az eredmenyt adja.
Megerősítve.
A scripted így is működne:
Persze a helyes megoldás nem ez, hanem a lokalizáció idomitása az inputodhoz:
tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE
TL;DR Kimaradt valamelyik profile-ból a
LC_NUMERIC=C