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?
- 5370 megtekinté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]\.-
- A hozzászóláshoz be kell jelentkezni
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.
- A hozzászóláshoz be kell jelentkezni
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 hozzászóláshoz be kell jelentkezni
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.)
- A hozzászóláshoz be kell jelentkezni
gawk -F\; '{print $1 "," $2 "," $3 "," $4 ","}' Cimek.csv
Igy pontos. Az oldal eltüntette az előző hsz-ből a backslasht.
- A hozzászóláshoz be kell jelentkezni
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!"
- A hozzászóláshoz be kell jelentkezni
Azért fenti feladatra a tr is jó:
tr \; , < Cimek.csv > Cimek2.csv
És ha valami multibájtos karakter bájtszekvenciájában pontosvesszőt talál, azt lecseréli jól.
- A hozzászóláshoz be kell jelentkezni
Létezik olyan, viszonylag elterjedt kódolás, amiben multibájtos szekvenciák tartalmazhatnak pontosvesszőt?
Még a legendásan elcseszett Shift-JIS sem ilyen, ott is csak a 0x40 vagy afölötti oktett lehet egy karakter második bájtja.
- A hozzászóláshoz be kell jelentkezni
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
- A hozzászóláshoz be kell jelentkezni
Megtörtént a fájlba irányítás is, de a hiba maradt az mint terminál kimeneten.
- A hozzászóláshoz be kell jelentkezni
A sorok végére még be kell tennem egy vesszőt. Ehhez már awk kell, nem? Vagy sed-del is megoldható?
- A hozzászóláshoz be kell jelentkezni
sed -e 's/;/,/g' -e 's/$/,/' test.csv >result.csv
-----
(&%;_98\<|{3W10Tut,P0/on&Jkj"Fg}|B/!~}|{z(8qv55sr1C/n--k**;gfe$$5a!BB]\.-
- A hozzászóláshoz be kell jelentkezni
Hasonlóan hibás a kimenet, csak így egyetlen vessző takar ki az elején egy karaktert nem több.
- A hozzászóláshoz be kell jelentkezni
Linkelje egy teszt fájlt, amivel hibásan működik nálad.
-----
(&%;_98\<|{3W10Tut,P0/on&Jkj"Fg}|B/!~}|{z(8qv55sr1C/n--k**;gfe$$5a!BB]\.-
- A hozzászóláshoz be kell jelentkezni
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.
- A hozzászóláshoz be kell jelentkezni
Nálam első jó, a második kettő viszont nem. OSX-en és Linuxon is próbáltam.
Ékezetektől megfosztott verzión mindegyik jó és az utolsó kettő rendben be is teszi a vesszőt a végére.
- A hozzászóláshoz be kell jelentkezni
Bocs, az utolsóban ugye fizikailag Ctrl-M-et írtál és nem ^ M (kétkarakteres) kombinációt?
- A hozzászóláshoz be kell jelentkezni
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).
- A hozzászóláshoz be kell jelentkezni