Prosíme přihlašte se nebo zaregistrujte.

Přihlašte se svým uživatelským jménem a heslem.
Vaše pomoc je stále potřeba!

Autor Téma: sed a specificky blok textu  (Přečteno 2817 krát)

Uran

  • Aktivní člen
  • *
  • Příspěvků: 341
sed a specificky blok textu
« kdy: 15 Března 2012, 08:30:30 »
Potreboval bych ze souboru vypsat jen urcite bloky textu. Jsou ohranicene unikatnim retezcem "###". Uvnitr bloku je slovo co hledam

Takze:

Kód: [Vybrat]
###
pin
pong
pan
###
dgd

dvdfg
dfg
dsd
sd
sdv
dg
dg
dsg
dgdgfgs


###
vfdfdf
dfsdfsf
ccc
###

dokazi vypsat vsechny bloky ohranicene ###

Kód: [Vybrat]
cat sed-test | sed -n '/###/,/###/p'jen nevim jak tam dostat podminku aby vypsalo jen ty, ktere obsahuji napr. pin.

Zkousel jsem:

Kód: [Vybrat]
cat sed-test | sed -n '/###/,/pin/,/###/p'
sed: -e výraz č. 1, znak 12: neznámý příkaz: „,“

ale to je asi pekna blbost.

Rad bych to resil pomoci bashe/sed/awk/grep. Perl a podobne moc nechapu.

"Pouze text v MS Wordu je opravdu čistý, příteli."

daysleeper

  • Stálý člen
  • **
  • Příspěvků: 1206
Re:sed a specificky blok textu
« Odpověď #1 kdy: 15 Března 2012, 11:45:02 »
Podle mě není možné v address range zadat více adres než dvě, takže budeš muset použít další sed příkaz nebo grep.
Kód: [Vybrat]
cat sed-test | sed -n '/###/,/###/p' | grep pong

Uran

  • Aktivní člen
  • *
  • Příspěvků: 341
Re:sed a specificky blok textu
« Odpověď #2 kdy: 15 Března 2012, 12:18:39 »
Podle mě není možné v address range zadat více adres než dvě, takže budeš muset použít další sed příkaz nebo grep.
Kód: [Vybrat]
cat sed-test | sed -n '/###/,/###/p' | grep pong

No me jde o to abych vypreparoval konkretni blok. Takze pokud to spravne chapu tak vyse uvedeny prikaz 1. vypreparuje bloky ohranicene ### 2. z techto bloku vypreparuje radky s pong coz ovsem nepotrebuji. Chci cele bloky s hledanym slovem. Jinak jeste je problem v tom, ze bloky nemaji pevny pocet radek, ale meni se - 3 a vice radku.
"Pouze text v MS Wordu je opravdu čistý, příteli."

ntz_reloaded

  • Lokaj
  • Závislák
  • ***
  • Příspěvků: 3735
  • skill :: ur home erly
Re:sed a specificky blok textu
« Odpověď #3 kdy: 15 Března 2012, 12:29:13 »
Kód: [Vybrat]
> printf "%s\n" a b a w a b a | sed '/^b/,/^b/s/a/x/'
a
b
x
w
x
b
a

^^ tohodle chces docilit ? asi to nechapu
tikejte mi, taky Vam tikam ...
song of the day - openSUSE, openindiana, DuckDuckGo
The noise ain't noise anymore, who's to blame, WHO'S TO BLAME ??

GdH

  • Moderátor
  • Závislák
  • ***
  • Příspěvků: 3176
    • GdH-Notes
Re:sed a specificky blok textu
« Odpověď #4 kdy: 15 Března 2012, 13:38:11 »
Kód: [Vybrat]
awk '/^###/{o=p;p="";getline};r&&!p{print substr(o,0,(length(o)-1));exit};{p=p$0"\n"};/pong/{r=1}'

Uran

  • Aktivní člen
  • *
  • Příspěvků: 341
Re:sed a specificky blok textu
« Odpověď #5 kdy: 15 Března 2012, 18:24:40 »
Kód: [Vybrat]
awk '/^###/{o=p;p="";getline};r&&!p{print substr(o,0,(length(o)-1));exit};{p=p$0"\n"};/pong/{r=1}'

Ok. Musim to nejak promyslet a po vikendu se ozvu. V bashi awk ... jsem zacatecnik a tu konstrukci awk moc nechapu. Asi se budu muset o bahi/awk/.... neco doucit. Takze bych tuto diskuzi na chvilku zmrazil a az to pochopim/vyresim tak dam vedet.
"Pouze text v MS Wordu je opravdu čistý, příteli."

daysleeper

  • Stálý člen
  • **
  • Příspěvků: 1206
Re:sed a specificky blok textu
« Odpověď #6 kdy: 15 Března 2012, 21:21:06 »
No me jde o to abych vypreparoval konkretni blok. Takze pokud to spravne chapu tak vyse uvedeny prikaz 1. vypreparuje bloky ohranicene ### 2. z techto bloku vypreparuje radky s pong coz ovsem nepotrebuji. Chci cele bloky s hledanym slovem. Jinak jeste je problem v tom, ze bloky nemaji pevny pocet radek, ale meni se - 3 a vice radku.
Aha, pak by mělo fungovat
Kód: [Vybrat]
sed '/###/,/###/{H;$!d;};x;/pong/!d'
Manuál třeba viz
http://www.grymoire.com/Unix/Sed.html

GdH

  • Moderátor
  • Závislák
  • ***
  • Příspěvků: 3176
    • GdH-Notes
Re:sed a specificky blok textu
« Odpověď #7 kdy: 15 Března 2012, 21:48:08 »
Kód: [Vybrat]
awk '/^###/{o=p;p="";getline};r&&!p{print substr(o,0,length(o)-1);exit};{p=p$0"\n"};/hledaný_výraz/{r=1}'
Důležité je, že v awk jsou proměnné netypové a dají se testovat a používat bez deklarace, prostě se při prvním použití samy vytvoří jako prázdné/nulové. Při použití ve stringu se bude taková proměnná chovat jako prázný řetězec, při výpočtech jako nula. Dokonce pokud bude v proměnné řetězec a vrazíte ji do matematického výrazu, bude se chovat jako nula.

Uvedený program dělá následující:
Do proměnné p si postupně načítá jednotlivé řádky souboru, které interpret awk drží vždy v proměnné $0, a odděluje je znakem nového řádku. {p=p$0"\n"}
Když narazí na řádek začínající ### odloží si obsah p (což je celý předešlý blok) do proměnné o, p smaže a načte nový řádek.
/^###/{o=p;p="";getline}
Pokud v daném bloku našel hledaný výraz, což indikuje neprázdná proměnná r ( /hledaný_výraz/{r=1} ) , a zároveň došel na konec bloku, což indikuje prázdná p, vytiskne celý blok odložený v proměnné o bez posledního znaku nového řádku a ukončí program.
r&&!p{print substr(o,0,(length(o)-1));exit}

Poskládané je to tak, aby se vyplivnul jen čistý blok, bez oddělovacích řádků.
« Poslední změna: 15 Března 2012, 22:13:09 od GdH »

Uran

  • Aktivní člen
  • *
  • Příspěvků: 341
Re:sed a specificky blok textu
« Odpověď #8 kdy: 16 Března 2012, 11:28:00 »
Dekuji. Je to vyreseno.

Nekde doma mam knihu http://www.abclinuxu.cz/clanky/recenze/awk-amp-sed-prirucka-pro-davkove-zpracovani-textu takze jdu studovat.
"Pouze text v MS Wordu je opravdu čistý, příteli."

GdH

  • Moderátor
  • Závislák
  • ***
  • Příspěvků: 3176
    • GdH-Notes
Re:sed a specificky blok textu
« Odpověď #9 kdy: 17 Března 2012, 15:30:01 »
Soudruzi, vy mě nakonec svými dotazy a špatnými řešeními ještě naučíte programovat sed a awk :D
Protože sed je přeci jen efektivnější než awk, opět jsem se začetl do manuálu a zaexperimentoval. Výsledkem je kratší a rychlejší řešení, ale netvrdím, že už to nejde optimalizovat:

Kód: [Vybrat]
sed -n '/###/{x;/hledaný_výraz/{s/^[^\n]*\n//;p;q};d};H'
Stejně jako mé awk řešení, vypíše pouze první blok, ve kterém se vyskytuje hledaný řetězec.

Ještě jedna poznámka. Obě má řešení fungují tak, že se vypíše výsledek při dosažení řádku obsahující delimiter, v tomto případě ###, tudíž vyžadují tento delimiter na konci každého bloku, který má být brán vážně. Naopak na začátku ho nepotřebují, blok se načítá vždy, pouze se při dosažení delimiteru nuluje, případně vytiskne.

Edit: I když je fakt, že vzhledem k prvnímu autorově příspěvku, kde píše, že umí vypsat všechny ohraničené bloky, jsem asi zadání nesplnil přesně.. Pak bych to opravil na:

Kód: [Vybrat]
sed -n '/###/,/###/{/###/{x;/hledaný_výraz/{s/^[^\n]*\n//;p;q};d};H}'
« Poslední změna: 18 Března 2012, 01:54:19 od GdH »

daysleeper

  • Stálý člen
  • **
  • Příspěvků: 1206
Re:sed a specificky blok textu
« Odpověď #10 kdy: 17 Března 2012, 19:13:26 »
Kód: [Vybrat]
sed -n '/###/,/###/{/###/{x;//{s/###\n//;p;q};d};H}'
No není sed krásný?  ;D

Uran

  • Aktivní člen
  • *
  • Příspěvků: 341
Re:sed a specificky blok textu
« Odpověď #11 kdy: 19 Března 2012, 12:46:32 »
Kód: [Vybrat]
sed -n '/###/,/###/{/###/{x;//{s/###\n//;p;q};d};H}'
No není sed krásný?  ;D

Je nadherny :-).
Ted prave strojove zpracovavam doc dokumenty, ktere nejsou konzistentni z hlediska formatovani tak s tim trochu zapasim, ale ono se to povede. Musi :)

Trochu jsem musel skript upravit aby se vypisovaly vsechny bloky a ne jen jeden. Ted to funguje k me spokojenosti.

Kód: [Vybrat]
#!/bin/bash
echo "Zadej entitu"
read hledam
sed -n "/#####/,/#####/{/#####/{x;/"$hledam"/{s/^[^\n]*\n/#####\n/;p};d};H}" file
« Poslední změna: 20 Března 2012, 13:35:57 od Uran »
"Pouze text v MS Wordu je opravdu čistý, příteli."

 

Provoz zaštiťuje spolek OpenAlt.