awk, ékezetek, szívás

Fórumok

Teljesen kiszámíthatatlanul, hibásan működik a (g)awk amint ékezetes szöveget tartalmazó fájlt kell feldolgozni vele.
Van erre valamilyen megoldás?

Hozzászólások

Kérdések: A problémás esetekben
– milyen kódolású a problémás fájl;
– milyen kódolás (locale) van beállítva?

Ha különbözőek, akkor:

iconv -c -f xxxx -t yyyy file | awk ...

Kiegészítés:
A jelen esetben a „-t yyyy” el is hagyható.

-----

(&%;_98\<|{3W10Tut,P0/on&Jkj"Fg}|B/!~}|{z(8qv55sr1C/n--k**;gfe$$5a!BB]\.-

Egy CSV fájlban kellett kicserélni a ; karaktert ,-re

gawk -F; '{print $1 "," $2 "," $3 "," $4 ","}' Cimek.csv

Címjegyzék volt a problémás csv fájlban, és a kereszt és vezetéknevek természetesen ékezetes betűkkel szerepeltek.
A végeredmény totál káosz, a vesszők fele a sorok elejére került, kitakarva a vezetéknevek első karaktereit. Miután kiszedtem az ékezetes betűket már teljesen jól működött az awk. De így Otvos Mate és hasonló ékezettelenített nevek vannak a kimeneten ami nem elegáns egy e-mailben.

Add ki az adott gépen a

locale

parancsot. Annak a kimenete elárulja, hogy a gépen milyen kódolás van beállítva.
Kérdezd le a csv file kódolását, Majd hasonlítsd össze az előzővel. Ha a kettő egyezik, akkor a gawk-nak nem szabadna hibáznia.

A fájl kódolásának lekérdezésére az enca parancsot szoktam használni (debianon az enca csomagban van). A tapasztalataim szerint a „file -i x.y” és az „uchardet x.y” nem mindig ad helyes eredményt.

-----

(&%;_98\<|{3W10Tut,P0/on&Jkj"Fg}|B/!~}|{z(8qv55sr1C/n--k**;gfe$$5a!BB]\.-

A csv fájl kódolása:
Universal transformation format 8 bits; UTF-8
CRLF line terminators

A locale beállítás: hu_HU.UTF-8
(A macbookomon valóban en_US.UTF-8 a locale, de ide csak azután töltöttem le a csv-t miután a szerveren elegem lett az ékezetek miatti szívásokból. De osx-en is ugyanaz volt a hiba, ami így érthető. De a linux szerveren nem.)

Ha nem életbevágó az awk használata, akkor a sed is jó ilyen egyszerű feladatra.
sed -e s'/;/,/'g Cimek.csv > Cimek2.csv
Szerintem ez akkor is jó, ha nem egyezik a fájl kódolása a rendszeren levővel.
--

nTOMasz
"The hardest thing in this world is to live in it!"

Erősen kétlem, és az a sejtésem, hogy ez a bemeneti fájl inkább egy rakás kocsivissza (0x0D) karaktert tartalmaz - meg az, hogy a kimenet fájlba átirányítása nem történt meg, hanem a terminálon megjelenő eredmény alapján született a konklúzió.

Akár jól tippelek, akár nem, a feladat utólagos ismeretében - ha csak sztringszerű mezőket tartalmaz a csv - (akármilyen eszközzel) a cserét így módosítanám:

s/";"/","/g

Hat ebben a fajlban nem unixos, hanem dosos sorvegjelek vannak, ahogy azt lx itt mar tobbszor jelezte. (cat -tev proba2.csv mutatja, fent emlitett enca proba2.csv meg mondja is.) Szoval ebben az iranyban kene elindulnod.


cat proba2.csv|sed -e 's/;/,/g' 

ez jo,


cat proba2.csv|sed -e 's/;/,/g' -e 's/$/,/'

ez pedig mar az altalad is emlegetett problemat mutatja.


cat proba2.csv|sed -e 's/;/,/g' -e 's/^M//' -e 's/$/,/'

Ez pedig mar megint jo.

Akkor még egyszer: szerintem a CR karakterek bolondítják meg a kimenetedet, de azt is csak látszólag.


$> cat crlf.txt
elso;sor
masodik;sor

negyedik;sor

$> file crlf.txt
crlf.txt: ASCII text, with CRLF line terminators
$> awk -F\; '{print $1 "," $2 ","}' crlf.txt
,lso,sor
,asodik,sor
,,
,egyedik,sor
,,
$> awk -F\; '{print $1 "," $2 ","}' crlf.txt  > crlf.out
$> less crlf.out
elso,sor^M,
masodik,sor^M,
^M,,
negyedik,sor^M,
^M,,
$> awk -F\; -vRS='\r\n'  '{print $1 "," $2 ","}' crlf.txt
elso,sor,
masodik,sor,
,,
negyedik,sor,
,,

Azaz:
1. nem mindig azt látjuk, ami a fájlban valójában ott van,
2. ha tudatjuk az awk-kal, hogyan néznek ki a rekordjaink (soraink), a kimenet is az elvárt alakot ölti (GIGO - ahogy a görög bölcs tartja).