Fórum Root.cz

Hlavní témata => Vývoj => Téma založeno: Kateřina 18. 02. 2013, 22:22:07

Název: Parsování souboru csv
Přispěvatel: Kateřina 18. 02. 2013, 22:22:07
Zdravím, potřebovala bych rozparsrovat soubor, ve kterém jsou jednotlivá slova oddělena čárkou. Potřebuji to udělat přím v bashi. Nevíte náhodou někdo jak na to? Je to vlastně csv soubor, který se používá pro kopírování zboží na web. Děkuji Musí to být v bashi
Název: Re:Parsování souboru csv
Přispěvatel: student 18. 02. 2013, 22:31:47
Co tak zmena IFS a potom read? To zvladne okrem bashu aj shell bez bashovskych featur.
Název: Re:Parsování souboru csv
Přispěvatel: Honza Vrana 18. 02. 2013, 22:32:28
Krasny den,

staci takove to nakopnuti ?

echo "jabka,hrusky,kakao" | cut -d\, -f2

Jinak pouzit nejaky textovy editor jako je sed nebo awk ale zalezi na tom co si predstavujete pod pojmem  "Parsování souboru csv" cily jake data ze souboru chcete ziskat a co snima chcete delat.

S pozdravem Honza Vrana
Název: Re:Parsování souboru csv
Přispěvatel: PanKapitanRUM 18. 02. 2013, 22:41:19
S CSV můžeš hodně snadno dojet na zákysu (vím o čem mluvím) a určitě bych to nedělal čistě v BASH.
Parser si můžeš napsat v PHP a bude to o poznání spolehlivější, PHP můžeš pouštět i z konzole.
Jestli na tom jsi jako moji zákazníci, pak se ti dříve nebo v později objeví čárka, já mám třeba položku něco jako "Dárek za 50,- Kč" a "Věc s kolem,světlem a motykou". Asi chápeš, že ty čárky v tom nadělají paseku, proto je dobré vstup ošetřit tak, abys měl jistotu, že Parser NIKDY nedostane špatná data, protože jinak se jebne a řešíš, nebo se nejebne a máš paseku v DB, což někoho nasere.
Název: Re:Parsování souboru csv
Přispěvatel: PanKapitanRUM 18. 02. 2013, 22:55:12
Doplním, že jsem se jistou dobu snažil v parseru používat regulérní výrazy, ale pokaždé se objevil větší špek ::) přesně ve stylu "Pepa vymyslel zcela blbuvzdornou věc a bůh mu dokázal, že umí udělat ještě většího blba." Od té doby mám parser udělaný tak, že kontroluji výstup, kde provádím čištění, aby se do parseru opravdu nikdy nedostalo nic, co by se mu nemuselo líbit. Pokud to máš tak udělané, můžeš to parsovat jen v Bash. Pokud máš eshop (my děláme Magento), tak je nejlepší to udělat pořádně, nejlépe neexportovat do CSV, ale do XML.
Jinak často stačí i jen jednoduchá úprava parseru, kdy se jako delimiter (oddělovač) použije středník ;
Bez středníku se hromada lidí prostě obejde, můžeš řádek testovat na počet středníků.

Například mějme řádek:
podprda;červená;c;500;605

A teď vývojový diagram:
A) provedeš otestování, kolik středníků je v řádku, pokud jich je víc než 4, pošleš výstup do LOG.TXT a přeskočíš záznam
B) pokud záznam není přeskočený, provedeš import
C) po dokončení importu zjistíš, jestli existuje LOG.TXT, tj. jestli se vůbec vytvořil, pokud ano, pošleš si ho mailem a smažeš ho

Tohle je poměrně použitelný způsob zpracování.
Splňuje to požadavky na stabilitu, tedy do DB se nikdy nesmí dostat svinstvo.
Splňuje to požadavek na upozornění, kdy ti přijde mail a ty ho můžeš předat dál, tj. neztrácíš chybu.
Splňuje to požadavek na jednoduchost, čím je řešení složitější, tím je v něm víc chyb a tedy nesplňuje požadavek na stabilitu, protože nezajistí, že se do DB nedostane svinstvo.

No dělej si s tím co chceš.
Název: Re:Parsování souboru csv
Přispěvatel: Náhodný kolemjdoucí 18. 02. 2013, 23:05:25
Doplním, že jsem se jistou dobu snažil v parseru používat regulérní výrazy, ale...

Jak praví lidové moudro: Máme-li problém, můžeme ho zkusit řešit pomocí regulárního výrazu. Pak budeme mít problémy dva.
Název: Re:Parsování souboru csv
Přispěvatel: PanKapitanRUM 18. 02. 2013, 23:10:09
S tím nemohu souhlasit, rozhodně bych to neoznačil za "problémy dva" ::)
Moje poslední funkční verze regulérního výrazu připomínala jádro Linuxu přepsané do BrainFucku (http://cs.wikipedia.org/wiki/Brainfuck (http://cs.wikipedia.org/wiki/Brainfuck))  ::) :-\ :o

Název: Re:Parsování souboru csv
Přispěvatel: zelen 18. 02. 2013, 23:45:02
S CSV můžeš hodně snadno dojet na zákysu (vím o čem mluvím) a určitě bych to nedělal čistě v BASH.
Parser si můžeš napsat v PHP a bude to o poznání spolehlivější, PHP můžeš pouštět i z konzole.
Jestli na tom jsi jako moji zákazníci, pak se ti dříve nebo v později objeví čárka, já mám třeba položku něco jako "Dárek za 50,- Kč" a "Věc s kolem,světlem a motykou". Asi chápeš, že ty čárky v tom nadělají paseku, proto je dobré vstup ošetřit tak, abys měl jistotu, že Parser NIKDY nedostane špatná data, protože jinak se jebne a řešíš, nebo se nejebne a máš paseku v DB, což někoho nasere.
IMHO psát vlastní program je nejhorší možnost (trvá to dlouho, první verze budou plné chyb a ostatní se s tím nebudou chtít učit). Existují spousty CSV parserů v nejrůznějších jazycích. Vybrat si ten správný zabere minimum času a všechny špeky už v něm budou vychytané.
Název: Re:Parsování souboru csv
Přispěvatel: Pavel 19. 02. 2013, 08:46:21
A teď vývojový diagram:
A) provedeš otestování, kolik středníků je v řádku, pokud jich je víc než 4, pošleš výstup do LOG.TXT a přeskočíš záznam
B) pokud záznam není přeskočený, provedeš import
C) po dokončení importu zjistíš, jestli existuje LOG.TXT, tj. jestli se vůbec vytvořil, pokud ano, pošleš si ho mailem a smažeš ho

Splňuje to požadavky na stabilitu, tedy do DB se nikdy nesmí dostat svinstvo.

Iba za predpokladu, ze tam nemate viacriadkovy zaznam.

Pouzivat dobrovolne CVS v dnesnej dobe mi pride, ako prejav ustrnutia v minulom tisicroci.
Název: Re:Parsování souboru csv
Přispěvatel: Radek Miček 19. 02. 2013, 10:28:01
Citace
Pouzivat dobrovolne CVS v dnesnej dobe mi pride, ako prejav ustrnutia v minulom tisicroci.

CSV je velmi jednoduchý formát, a pokud dostačuje, není IMO důvod použít složitější.
Název: Re:Parsování souboru csv
Přispěvatel: JardaP . 19. 02. 2013, 11:01:59
Iba za predpokladu, ze tam nemate viacriadkovy zaznam.

No, to jaksi u CSV nebyva zvykem, ne?
Název: Re:Parsování souboru csv
Přispěvatel: Radek Miček 19. 02. 2013, 11:08:05
Citace
No, to jaksi u CSV nebyva zvykem, ne?

A proč ne?
Název: Re:Parsování souboru csv
Přispěvatel: Blabla 19. 02. 2013, 11:37:31
Protože standardní oddělovač je CRLLF?
Název: Re:Parsování souboru csv
Přispěvatel: JardaP . 19. 02. 2013, 21:00:51
Citace
No, to jaksi u CSV nebyva zvykem, ne?

A proč ne?

Protoze by to bylo prakticke, jak hrabe do postele.  http://tools.ietf.org/html/rfc4180#page-2
Název: Re:Parsování souboru csv
Přispěvatel: Radek Miček 19. 02. 2013, 21:10:28
Citace
Protoze by to bylo prakticke, jak hrabe do postele.  http://tools.ietf.org/html/rfc4180#page-2

Proč by to bylo praktické, jak hrábě do postele?

V RFC čtu:

Kód: [Vybrat]
6.  Fields containing line breaks (CRLF), double quotes, and commas
    should be enclosed in double-quotes.  For example:

    "aaa","b CRLF
    bb","ccc" CRLF
    zzz,yyy,xxx

Takže CSV může obsahovat víceřádkový záznam, ne?
Název: Re:Parsování souboru csv
Přispěvatel: JardaP . 19. 02. 2013, 21:38:11
Ja tam hlavne ctu:

  1.  Each record is located on a separate line, delimited by a line
       break (CRLF).  For example:

       aaa,bbb,ccc CRLF
       zzz,yyy,xxx CRLF

CSV podle bodu 6. je prakticke, jak hrabe do postele a pokud vite o aplikaci, ktera toho vyuziva, tak by me zajimalo, jaka. Clovek by nejspise akorat narazil na problem s importem do vetsiny ostatnich aplikaci a parsovat to skriptem by byl pekny svrab. Mozna, ze to nekde existuje, ale nemyslim si, ze by to bylo obvykle.
Název: Re:Parsování souboru csv
Přispěvatel: Radek Miček 19. 02. 2013, 21:47:01
Citace
parsovat to skriptem by byl pekny svrab

Napsat CSV parser (v rozumném jazyce), který to rozparsuje, je úkol na méně než 10 řádků.

Citace
Mozna, ze to nekde existuje, ale nemyslim si, ze by to bylo obvykle.

Přijde mi to docela normální (třeba pro uložení ceníku s popisem produktů).
Název: Re:Parsování souboru csv
Přispěvatel: neruda 19. 02. 2013, 22:02:19
Citace
parsovat to skriptem by byl pekny svrab

Napsat CSV parser (v rozumném jazyce), který to rozparsuje, je úkol na méně než 10 řádků.

Citace
Mozna, ze to nekde existuje, ale nemyslim si, ze by to bylo obvykle.

Přijde mi to docela normální (třeba pro uložení ceníku s popisem produktů).

hmmm pokud dovedete nahradit treba opencsv 10ti radky, tak jste machr,
jinak zas jenom prilis sebevedomy smudla
Název: Re:Parsování souboru csv
Přispěvatel: PanKapitanRUM 19. 02. 2013, 22:03:16
CRLF na konci řádku znamená že:
Řádek se dá načíst pomocí metody ReadLine, která čte od začátku řádku až po CRLF.

Until(EOF) {ParseRecord(ReadLine(FromStream));}

Případně testovat jednoduše na EOL.

Jde to tedy jednoduše zpracovat, celý soubor načteš jedním řádkem kódu a všechno udělá parser.
Pokud by CSV obsahovalo CRLF, tak by se to muselo načíst proudem a zpracovávat daleko složitěji.
Proto jsem ještě CRLF v CSVčku nikde neviděl.  ::)
Název: Re:Parsování souboru csv
Přispěvatel: PanKapitanRUM 19. 02. 2013, 22:10:03
Machr napsal:
Přijde mi to docela normální (třeba pro uložení ceníku s popisem produktů).

jinak zas jenom prilis sebevedomy smudla

Pane Nerudo, nebuďte nerudný, vy snad nevidíte ty znalosti?!?
Dokonce ví, že popis produktů se podle HTML verze 6 odděluje zase jako v DOS pomocí CRLF a už ne
. :o
Pic kozu do vazu!
Název: Re:Parsování souboru csv
Přispěvatel: JardaP . 19. 02. 2013, 22:11:00
Citace
Mozna, ze to nekde existuje, ale nemyslim si, ze by to bylo obvykle.

Přijde mi to docela normální (třeba pro uložení ceníku s popisem produktů).

Nicmene se asi shodneme na tom, co jsem rekl vyse: Neni to obvykle. Popiralo by to jaksi vyhody jednoduchosti CSV. Pokud musite exportovat neco, kde naprosto nutne musi byt prechody na novy radek a nemuzete je treba nahradit nejakou nesmyslnou kombinaci znaku, kterou si za tim ucelem vymyslite, asi byste udelal lepe, kdybyste zvolil jiny format.
Název: Re:Parsování souboru csv
Přispěvatel: PanKapitanRUM 19. 02. 2013, 22:11:53
Jde to tedy jednoduše zpracovat, celý soubor načteš jedním řádkem kódu a všechno udělá parser.
Pokud by CSV obsahovalo CRLF, tak by se to muselo načíst proudem a zpracovávat daleko složitěji.
Proto jsem ještě CRLF v CSVčku nikde neviděl.  ::)

Chybí mi edit ::)
Samozřejmě myslím CRLF mimo konce řádek, jinak jsem samozřejmě v CSVčkách CRLF viděl  ;D
Název: Re:Parsování souboru csv
Přispěvatel: PanKapitanRUM 19. 02. 2013, 22:13:56
Nicmene se asi shodneme na tom, co jsem rekl vyse: Neni to obvykle. Popiralo by to jaksi vyhody jednoduchosti CSV. Pokud musite exportovat neco, kde naprosto nutne musi byt prechody na novy radek a nemuzete je treba nahradit nejakou nesmyslnou kombinaci znaku, kterou si za tim ucelem vymyslite, asi byste udelal lepe, kdybyste zvolil jiny format.

Járo, konce řádek v popisu zboží eshopu se budou nejspíš oddělovat pomocí značky
 ;)
Název: Re:Parsování souboru csv
Přispěvatel: JardaP . 19. 02. 2013, 22:25:30
To je jedno, at si je kazdy oddeluje, cim chce. Ale ten clovek tam naprosto nutne potreboval mit CRLF, tak at si ho tam ma.
Název: Re:Parsování souboru csv
Přispěvatel: Radek Miček 19. 02. 2013, 22:36:01
Citace
hmmm pokud dovedete nahradit treba opencsv 10ti radky, tak jste machr,
jinak zas jenom prilis sebevedomy smudla

Nesliboval jsem, že nahradím nějakou knihovnu.

Následující kód zvládne rozparsovat CSV (je tolerantnější než RFC - jako oddělovač záznamů povoluji i samotné CR nebo LF, neboť Libre Office používá samotné LF):

Kód: [Vybrat]
import Control.Applicative ((<*), pure)
import Text.ParserCombinators.Parsec

csv = record `sepEndBy` (try (string "\r\n") <|> pure "" <* oneOf "\n\r") <* eof
record = (quoted <|> (many (noneOf ",\n\r\""))) `sepBy` char ','
quoted = between (char '"') (char '"') $
         many (noneOf "\"" <|> try (string "\"\"" >> pure '"'))

Použití:

Kód: [Vybrat]
pure (parse csv "") <*> readFile "pok.csv"
Název: Re:Parsování souboru csv
Přispěvatel: JardaP . 19. 02. 2013, 22:41:54
Tak jo. A ted jeste jednou v Bashi. :-)
Název: Re:Parsování souboru csv
Přispěvatel: PanKapitanRUM 19. 02. 2013, 23:08:58
V BASHI a bez použití CRLF resp. LF pro Linux jako oddělovače řádku a nesmí to vypadat jako program v BrainFucku ani nabobtnat víc než o pár řádek.
Název: Re:Parsování souboru csv
Přispěvatel: Mirek Prýmek 19. 02. 2013, 23:53:43
Jinak často stačí i jen jednoduchá úprava parseru, kdy se jako delimiter (oddělovač) použije středník ;
Jak říká heslo konzervativců, "i po staru se dá žít!" :) Škoda, že pro samé debaty, jestli je praktičtější čárka, středník nebo srdíčko, se často zapomíná, že ASCII má netisknutelné znaky FS, GS, RS, US (file separator, group separator, atd.), které jsou určené přesně na tohle a pravděpodobnost, že se vyskytnou někde v textu, je dost malá (bacha ale na Unicode, to je prevít!). Nikdy nebude nulová, ale bude výrazně menší než u jakéhokoli tisknutelného znaku. To už si musí každý zvážit sám, jakou úroveň neprůstřelnosti potřebuje...

Jinak k té vášnivé debatě okolo CSV, myslím, že se tady míchají dohromady dvě věci:
1. CSV jako to, co je definováno zmíněným standardem
2. poor man CSV, čili "to je přece když jako oddělovač mám čárku"

To první se ani zdaleka nedá parsovat rozdělením podle oddělovače, protože zná hodnotu v uvozovkách (což je přesně ten háček, na kterým jste se v tom mariáši s citacemi RFCčka chytili...)
Název: Re:Parsování souboru csv
Přispěvatel: Pavel 20. 02. 2013, 03:58:47
Proto jsem ještě CRLF v CSVčku nikde neviděl.  ::)

Veci ktore som v zivote nevidel je vela, ale na nestastie medzi ne nepatri uvedena zalezitost.

Problem s CSV je v tom, ze narod ho pouziva nie ako format s nejakym RFC ale ako "to jednoduche cosi, co so vysypem z databazy a oddelim vybranym znakom" (vid toto vlakno).

CSV je velmi jednoduchý formát, a pokud dostačuje, není IMO důvod použít složitější.

CSV je format ku ktoremu musite mat doplnujuce informacie o tom, ako su pouzivane zakladne typy ako datum a cisla, ci ake je pouzite kodovanie.
Je prudko praktickejsie pouzit format, ktory nepotrebuje samostatny manual k jeho citaniu.
Název: Re:Parsování souboru csv
Přispěvatel: PanKapitanRUM 20. 02. 2013, 09:25:19
Veci ktore som v zivote nevidel je vela, ale na nestastie medzi ne nepatri uvedena zalezitost.
Problem s CSV je v tom, ze narod ho pouziva nie ako format s nejakym RFC ale ako "to jednoduche cosi, co so vysypem z databazy a oddelim vybranym znakom" (vid toto vlakno).

Co ti na to mám říct?
Já těch věcí v životě viděl hodně, hlavně eshopů a CSVček, ale CRLF jako oddělovač okolo mě za 20 let vážně nikdy nešel.
Ale budu si pamatovat, že existují lidé jako ty, kteří by to tak byli schopní udělat ::) a že tedy musím příště věci dělat víc blbůmvzdorné  ::)
Sám sis o to řekl  ::)
Název: Re:Parsování souboru csv
Přispěvatel: Honťa 20. 02. 2013, 10:50:53
Citace
No, to jaksi u CSV nebyva zvykem, ne?

A proč ne?

Dělám systémové integrace můžu ti říct, že csv soubory, které mají několik stovek tisíc až milióny řádků nejsou vůbec raritou. V tom na čem dělám je průměrná velikost csv souboru tak 25MB ;)