Fórum Root.cz
Hlavní témata => Vývoj => Téma založeno: 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
-
Co tak zmena IFS a potom read? To zvladne okrem bashu aj shell bez bashovskych featur.
-
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
-
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.
-
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š.
-
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.
-
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
-
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é.
-
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.
-
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ší.
-
Iba za predpokladu, ze tam nemate viacriadkovy zaznam.
No, to jaksi u CSV nebyva zvykem, ne?
-
No, to jaksi u CSV nebyva zvykem, ne?
A proč ne?
-
Protože standardní oddělovač je CRLLF?
-
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
-
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:
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?
-
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.
-
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ů.
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ů).
-
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ů.
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
-
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. ::)
-
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!
-
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.
-
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
-
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
;)
-
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.
-
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):
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í:
pure (parse csv "") <*> readFile "pok.csv"
-
Tak jo. A ted jeste jednou v Bashi. :-)
-
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.
-
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...)
-
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.
-
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 ::)
-
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 ;)