Fórum Ubuntu CZ/SK
Ubuntu pro osobní počítače => Software => Příkazový řádek a programování pro GNU/Linux => Téma založeno: JohnDoe 16 Února 2009, 20:11:07
-
Ahoj, resim v bashi par automatizovanejch veci a potrebuju z toho sed-em vyfiltrovat neco do promenne. Pokud je vstupni soubor v utf-8 kodovani, vse funguje jak ma, ale beda, jak to je v kodovani iso, pak to proste nefunguje a netusim proc. Pomuze mi nekdo? ;)
kodovani iso:
user@linux:~/ab> cat test.txt
P��li� �lu�ou�k� k�n �p�l ��belsk� �dy trocha ascii (to co hledam) trocha ascii blab��li� �lu�ou�k� k�n �p�l ��belsk� �dy.
user@linux:~/ab> sed -e 's/.*(/x/' -e 's/).*/x/' test.txt
P��li� �lu�ou�k� k�n �p�l ��belsk� �xto co hledamx��li� �lu�ou�k� k�n �p�l ��belsk� �dy.
kodovani utf-8:
user@linux:~/ab> cat test.txt
Příliš žluťoučký kůn úpěl ďábelské ódy trocha ascii (to co hledam) trocha ascii blabříliš žluťoučký kůn úpěl ďábelské ódy.
user@linux:~/ab> sed -e 's/.*(/x/' -e 's/).*/x/' test.txt
xto co hledamx
user@linux:~/ab>
Takze, mam retezec v libovolnym kodovani, ktery nejsem schopnej ovlivnit ani zjistit, soucasti toho retezce je cosi v zavorce, co z toho potrebuju vycucnout a pouzit. V cygwinu mi to maka uplne bez problemu, na linuxu (opensuse) vsak ne :(
Diky za jakoukoliv radu.
-
Jestli to třeba není tím, že utf-8 používá jiný princip kódování než iso-8859-2 a bohužel celé Ubuntu je v utf-8
-
Pokud požadujete, aby byl textový soubor v určitém kódování, musíte ho v tom konkrétním kódování pořídit. A vy jste pořizoval soubor v iso-8859-2 a přitom jste ho psal v kodování utf-8, a to má jiný PRINCIP kódování znaků. Kdybyste ho psal třeba ve windows-1250 (teď jsem si odplivnul :) ) , tak by to aspoň pro mě nebyl takový problém, kdybych věděl ASCII kód konkrétního znaku.
-
`man iconv` // nic jineho me nenapada .. sady nejdou mixovat a muj system nema vubec nainstalovano ISO88592 .. s iconv to funguje
-
Ano, nove linuxy jsou uz asi vsecky v utf-8, coz ovsem neznamena, ze by sed nemel fungovat s jinyma kodovanima ;) Aspon ja ted nevidim jediny rozumny duvod, proc by tomu tak melo byt. Jestli vymenim nejakej znak (bajt) za jinej, tak je prece jedno, jakej kod ma v tabulce, ne?
Problem je v tom, ze tecka "." by mela matchovat libovolnej znak, ale iso znaky nematchuje. A to je ten problem. Ale nerozumim tomu, stejne to je a vzdy bude jenom sekvence bajtu a s jako takovou by to prece melo pracovat. Takze, jak donutit sed, aby s tim pracoval?
iconv znam a hojne pouzivam jinde. Potiz je v tomto pripade v tom, ze nevim, v jaky znakovy sade ten vstupni soubor bude :-\
Update: kdyz je vstup ve windows-1250 (taky jsem si uplivnul ;D ) tak to taky nefunguje. Proste cokoliv neunicode sed nebere jako znak ::)
-
Pro objasnění (že urf-8 právě není jako ASCII znak za znak a že si to nevymýšlím) : http://cs.wikipedia.org/wiki/UTF-8
-
UTF-8 pouziva dva bajty pro jeden znak. Proto by to spis NEmelo fungovat opacne ;D Proc sed do toho vubec micha nejaky tabulky? Vzdyt jestli mam na vstupu 4 bajty a jsou to v nejake tabulce 2 jen znaky a v jine 4 by mu mohlo byt uplne putna. Aspon sed v cygwinu na nejake tabulky z vysoka dlabe a tak by to podle meho melo byt.
To jsem teda s bashem pekne narazil. Jestli to kvuli tomu budu predelavat do php nebo perlu, tak me vomeje :(
-
> cat xxx
Příliš žluťoučký kůn úpěl ďábelské ódy trocha ascii (to co hledam) trocha ascii blabříliš žluťoučký kůn úpěl ďábelské ódy.
## prevedeme soubor do ISO88592
iconv -f utf8 -t ISO88592 <(cat xxx) >yyy
## koukneme se
> cat yyy
P��li� �lu�ou�k� k�n �p�l ��belsk� �dy trocha ascii (to co hledam) trocha ascii blab��li� �lu�ou�k� k�n �p�l ��belsk� �dy.
## precteme primo ze souboru v iso-8859-2
> perl -Xne 'use Encode; $_ = decode("ISO88592", $_), print' <yyy
Příliš žluťoučký kůn úpěl ďábelské ódy trocha ascii (to co hledam) trocha ascii blabříliš žluťoučký kůn úpěl ďábelské ódy.
## primo v perlu to prozeneme pozadovanym RE
> perl -ne 'use Encode; $_ = decode("ISO88592", $_); s@^.*\((.*)\).*$@x\1x@; print' <yyy
xto co hledamx
-
Nettezzaumane dekuji, tohle opravdu vypada jako reseni. Od tebe me konstruktivni rada dvojnasob tesi :)
Potiz je v tom, ze se snazim udelat neco jednoducheho, co mi pobezi na woknech (v cygwinu) i na linuxu a instalovat na ty woknovy stanice kvuli tomu jeste perl se mi uprimne moc nechce... Ten skript bude mit asi 200 radku a jen kvuli jednomu radku v perlu bych musel na stanice instalovat zbytecnych 20 mega navic :(
Ja vim, jsem nevdecnik, vid? Nemel bys neco mene zraveho v pravem rukavu? ;)
EDIT: Tak jsem zjistil, ze to muzu asi prevest pomoci iconvu na utf-8 a pak proste pracovat s utf-8. Yed jeste aby to fungovalo v cygwinu, ale to zjistim az zejtra :) Iconvu je totiz asi uplne jedno, co mu nastavim jako from, proste to zkonvertuje do utf-8 a sed to bude mit v utf-8, coz vyzaduje :)
Takze nova, a mnohem jednodussi otazka, zni: Jak nahradim tvrdou mezeru v utf-8 ("\u00A0") za mekkou (''\x20").
Toto bohuzel nefunguje:
sed -e 's/\u00A0/ /g'
(ani toto: sed -e 's/\uA0/ /g')
-
Nettezzaumane dekuji, tohle opravdu vypada jako reseni. Od tebe me konstruktivni rada dvojnasob tesi :)
.. ;) uh.
.. to nebude afaik tak jednoduche .. vzdy budes muset pouzit nejakou funkci aby jsi prevedl data v INPUT streamu do pozadovane znakove sady pokud se INPUT lisi.. vzdy budes muset volat mejakou funkci nebo program co to udela, protoze to nejde rozpoznat automaticky
-
JohnDoe: Nic ve zlém, jen jsem chtěl objasnit, proč za to bash nemůže. Problém je právě v tom, že 1 konkrétní znak může být 1 až 6 bytů dlouhý. A jak se v tom ten chudák bash má vyznat. Samozřejmě pro znaky v původním ASCII má 1 znak 1 byte. utf-8 je Unicode, ale zkrácený, aby se ušetřilo maximum místa v souborech při ukládání.
-
drhlik: jasne, vsak nic ve zlem :)
nettezzaumana: tak ta "tvrda mezera" je kupodivu sekvence C2A0, ne 00A0. A tohle C2A0 potrebuju replacnout za normalni 20. Nevim, proc to na tom vstupu takhle leze, kazdopadne v prohlizeci to vypada jako mezera. A to C2A0 se mi ne a nedari replacnout :( Jestli to pres sed nepujde, nemas nejakej napad, jak replacovat v "binarnim" souboru? (bez perlu a dalsich x mega baliku navic)
-
Tak uz mi to funguje :) Nakonec jsem tu podivnou tvrdou mezeru C2A0 replacnul takto:
sed -e 's/\xC2\xA0/ /g'
Netusim, proc mi to pred tim neslo. Clovek furt neco zkousi a jak mu to nejde, tak pak si neda dohromady ani 1 + 1 :)
Dekuji za pomoc.
-
coze .. ukaz mi prosimte aplikovanej sedovskej vyraz na ::
iconv -t ISO88592 <(echo "Příliš žluťoučký kůn úpěl ďábelské ódy trocha ascii (to co hledam) trocha ascii blabříliš žluťoučký kůn úpěl ďábelské ódy.") | sed vyraz
## nicmene takto prevedene input z kodovani FOO do kodovani ORG
perl -MEncode -ne '$_ = decode("FOO", $_); print encode("ORG", $_)' <input
## nebo jeste lepe
perl -ne 'use Encode; print encode("ORG", decode("FOO", $_))' <input
-
Mas pravdu, ze to nejde. Nastesti me ta omacka okolo nezajima a ta vec v zavorce je jen normalni ascii :)
Takze si reknu, ze vstup bude iso-8859-2 (i kdyz to je treba windows-1250), a at to je co chce, prevedu to na utf-8 a kaslu na to, ze vylezou nesmysly. Dulezite je, ze ta vec v zavorce, coz je ascii, se nemeni, a s utf-8 mi sed uz normalne pracuje, a to je to, oc mi jde :)
vstup ve windows-1250:
user@linux:~/ab> cat test.txt
P��li� �lu�ou�k� k�n �p�l ��belsk� �dy trocha ascii (to co hledam) trocha ascii blab��li� �lu�ou�k� k�n �p�l ��belsk� �dy.
user@linux:~/ab> iconv -f iso-8859-2 -t utf-8 test.txt | sed -e 's/\xC2\xA0/x/g' -e 's/.*(//g' -e 's/).*//g'
to co hledam
vstup v utf-8:
user@linux:~/ab> cat test.txt
Příliš žluťoučký kůn úpěl ďábelské ódy trocha ascii (to co hledam) trocha ascii blabříliš žluťoučký kůn úpěl ďábelské ódy.
user@linux:~/ab> iconv -f iso-8859-2 -t utf-8 test.txt | sed -e 's/\xC2\xA0/x/g' -e 's/.*(//g' -e 's/).*//g'
to co hledam
Jen pro zajimavost, tohle vyleze z neceho, co je v utf-8, o kterym predpokladame, ze je to v iso-8859-2, a prevadime to na utf-8:
PĹĂliĹĄ ĹžluĹĽouÄkĂ˝ kĹŻn ĂşpÄl ÄĂĄbelskĂŠ Ăłdy trocha ascii (to co hledam) trocha ascii blabĹĂliĹĄ ĹžluĹĽouÄkĂ˝ kĹŻn ĂşpÄl ÄĂĄbelskĂŠ Ăłdy.
Nicmene to ascii nastesti tu "dvojitou" konverzi utf prezije :)
-
no, to neni moc ciste reseni .. dat perl windowsum neni zadnej zlocin
-
koukni na program enca (http://linux.die.net/man/1/enca), mozna by ti pomohl.. ikdyz to neni 100% spolehlive.
-
koukni na program enca (http://linux.die.net/man/1/enca), mozna by ti pomohl.. ikdyz to neni 100% spolehlive.
.. hoch se brani jakymkoliv aplikacim navic ..
ps. a uz jsme prisli na perl a iconv ;) .. vymysli radsi jak v nativnim windowsackem prostredi prevest neinteraktivne plaintext file z FOO do ORG ..
-
ps. a uz jsme prisli na perl a iconv ;)
ja tu encu uvadel prave kvuli automaticke detekci pouziteho kodovani. ;)
-
Taky z toho reseni nejsem 2x nadsenej, ale horsi by to bylo, kdybych kvuli jednomu radku instaloval na wokna perl, proste kanonem na vrabce :)
Enca beru na vedomi, diky za tip, treba se to bude nekdy hodit, ale snazim se tech prikazu pouzit co nejmin.