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: TIBOR 29 Září 2015, 09:20:03

Název: Grep a bodka.
Přispěvatel: TIBOR 29 Září 2015, 09:20:03
Zdravim.
Riesil som ulohu kde som mal spocitat vsetky bodky v dokumente, ale kedze bodka je specialny znak mal som s tym problem. Nakoniec som vygooglil grep -c [.] . Je aj iny sposob ako grep-u povedat ze bodka ma byt obycajny znak a nie specialny?
Cely prikaz vyzeral
Kód: [Vybrat]
sed 's/ /\n/'g 'Dokument bez názvu' | grep -c [.]
Název: Re:Grep a bodka.
Přispěvatel: Myrmica 29 Září 2015, 09:55:58
Normálně regulární výrazy berou bodku jako jakýkoli znak. Pokud chceš aby bala brána jako bodka (tečka :D ) tak ji napiš např takto:
Kód: [Vybrat]
grep "\."Možná ani ty uvozovky tam nemusí být.
Tohle platí pro všechny meta znaky.
Mrkni třeba sem: www.regularnivyrazy.info/regularni-vyrazy-zaklady.html#.VgpDqJcxf7B
Název: Re:Grep a bodka.
Přispěvatel: ntz_reloaded 29 Září 2015, 10:31:10
Kód: [Vybrat]
> cat *.php | perl -pe 's/[^.]//g' | wc -m
307186

^^ treba takto :) ... nicmene docela by me zajimalo, jak to udelat sedem ...  's/[^.]//g' prekvapive v sedu nefunguje jak bych cekal (tedy oznac kazdy znak krome tecky) ..
Název: Re:Grep a bodka.
Přispěvatel: Myrmica 29 Září 2015, 10:46:45
Předpokládám, že by to mělo vypadat takto:
Kód: [Vybrat]
's/[^\.]//g'Na všechny metaznaky by měla fungovat ta escape sequence a \. by měl být brán jako jeden znak.
Název: Re:Grep a bodka.
Přispěvatel: ntz_reloaded 29 Září 2015, 10:50:25
Předpokládám, že by to mělo vypadat takto:
Kód: [Vybrat]
's/[^\.]//g'Na všechny metaznaky by měla fungovat ta escape sequence a \. b\ měl být brán jako jeden znak.

predpokladat (myslet si) neznamena vedet ;) ... se divim, ze si to nevyzkousis ... tohle bohuzel nefunguje .. a apropos, pokud vim, tak v [] se ne-escapuje
Název: Re:Grep a bodka.
Přispěvatel: Myrmica 29 Září 2015, 12:02:55
No ten výraz mi funguje:
Kód: [Vybrat]
$ echo s/f//g | grep 's/[^\.]//g'
s/f//g
$ echo s/.//g | grep 's/[^\.]//g'
$
Nevím co hledáš, ale na uvedenou řadu znaků to funguje.
Pokud tobě ne, tak používáš špatný linux :D
Název: Re:Grep a bodka.
Přispěvatel: ntz_reloaded 29 Září 2015, 12:32:02
ne, tohle samozrejme nefunguje .... ani v tech tvejch prikladech :D

's/[^.]//g' ma odstranit vsechny znaky a nechat jen tecky a wc -m je spocita :D

Kód: [Vybrat]
$ echo s/f//g | grep 's/[^\.]//g'
s/f//g
$ echo s/.//g | grep 's/[^\.]//g'
$

^^ tady si tusim chtel dat misto grepu sed :D .... ale i tak ti to nebude fungovat (a prekvapive ani s grepem to nefunguje) ... melo by to delat neco takovyhleho (demonstruji na dmesg):

Kód: [Vybrat]
# dmesg | tail -33| perl -pe 's/[^.]//g'
............................................................

ps. ono to v grepu polo-funguje:

Kód: [Vybrat]
# dmesg | tail -33| sed 's/[^.]//g'
.
.
.
.
.
.
..
..
..
..
..
..
..
..
..
..
..
..
..
..
..
..
..
..
..
..
..
..
..
..
..
..
..

^^ akorat to neodstranuje \n a mozna neco jineho, takze to je nepouzitelne
Název: Re:Grep a bodka.
Přispěvatel: Martin Šácha 29 Září 2015, 13:40:36
Kód: [Vybrat]
dmesg | tail -33| sed 's/[^.]//g' | tr -d [:cntrl:] | grep '\.'
"tr" zlikviduje bordel
"grep" na konci vygeneruje prompt na novem radku
Název: Re:Grep a bodka.
Přispěvatel: ntz_reloaded 29 Září 2015, 13:47:19
Kód: [Vybrat]
> dmesg | tail -33| sed 's/[^.]//g' | tr -d '\n' | wc -m
60

> dmesg | tail -33| sed 's/[^.]//g' | tr -d '\n' | grep '\.' | wc -m
61

> dmesg | tail -33 | perl -pe 's/[^.]//g' | wc -m
60

^^ tady porad nekomu neco nedochazi :) ... novej radek je taky znak, pokud mas spocitat pocet tecek v inputu a beres to takto znakove, tak tam ten novej radek asi spis nechces
Název: Re:Grep a bodka.
Přispěvatel: Martin Šácha 29 Září 2015, 13:51:24
Takze opet zdrava vyziva reprezentovana grepem zcela k nicemu  :D
Název: Re:Grep a bodka.
Přispěvatel: ntz_reloaded 29 Září 2015, 14:02:10
Takze opet zdrava vyziva reprezentovana grepem zcela k nicemu  :D
abych se priznal, tak me samotneho docela dost prekvapilo, ze ten sed nema nejakej "mod" aby ten soubor cetl celej a ne line by line .... ja osobne sed nepouzivam dlouhy roky .. driv jsem ho pouzival, ale stvalo me, ze ta implementace je vsude jina (linux, solaris, aix) a 100% jsem se preorientoval na perl
Název: Re:Grep a bodka.
Přispěvatel: Myrmica 29 Září 2015, 14:31:55
Takže jsem to udělal trochu podle toho co chtěl ntz_reloaded, ale v sedu si nejsem (na rozdíl od regulárních výrazů) úplně jistý.  Zvláště když se sed tváří že je podporuje a není to zcela pravda.
Kód: [Vybrat]
dmesg | tail -33| sed -r 's/[^.]//g' | sed -e :a -e '$!N; s/\n//; ta'Prostě jsem řešil klasický regulární výraz a ne celý sedovský výraz. Sypu si popel na hlavu :D.
Určitě by to šlo dostat to do jednoho příkazu, ale to teď nejsem schopen napsat :D.
Název: Re:Grep a bodka.
Přispěvatel: TIBOR 29 Září 2015, 21:21:09
Uff, na par bodiek ste sa pekne rozbehli. :D Vdaka vsetkym za inspiracie.
Název: Re:Grep a bodka.
Přispěvatel: GdH 30 Září 2015, 01:19:30
Nedalo mi to, abych to nezkusil vyřešit přes buffer.  Dokonce je ten sed  POSIX způsobilý:
Kód: [Vybrat]
dmesg | tail -33| echo -n $(sed -n 'H;${x;s/[^.]//gp}') | wc -msed ale asi výstup tisknout rovnou bez koncového newline neumí..

ještě awk:
Kód: [Vybrat]
dmesg | tail -33| awk '{gsub(/[^.]/,"");printf $0}' | wc -m
Ale ten Perl je tu víc než dvakrát rychlejší, než awk, i sed.

Mimochodem:
... nicmene docela by me zajimalo, jak to udelat sedem ...  's/[^.]//g' prekvapive v sedu nefunguje jak bych cekal (tedy oznac kazdy znak krome tecky) ..
Tohle naopak funguje přesně podle očekávání, vzhledem k tomu, že sed je řádkový procesor, fungující tudíž ve smyčce typu while read line; do ...; done ;)

Edit: A řádově rychlejší je pak trdelník:
Kód: [Vybrat]
dmesg | tail -33| tr -cd . | wc -m