Fórum Root.cz
		Hlavní témata => Software => Téma založeno: Ħαℓ₸℮ℵ ␏⫢ ⦚  07. 02. 2024, 11:31:55
		
			
			- 
				Nemohu za boha přijít na to jak grepem vrátit jen první výskyt v jednořádkovém vstupu. -m1 nepomáhá. Jde to řešit jinak než  přidáním |head -n1 ? Z výkonnostních důvodů
			
- 
				co treba neco, co vrati vyraz dle patternu nebo taky nic, pokud tam neni:
 
 sed -E 's/^(.*)((regex)|())(.*)$/\2/'
- 
				Tak si na to napis skript, ze budes grepu v cykle davat na spracovanie po jednom subore a zakazdym checknes RC ci bol uspesny, alebo nie. V pripade uspechu ukoncis cyklus.
 
 priblizne takto:
 #!/bin/bash
 search_string="foo bar"
 files=$(ls *.txt)
 for file in $files; do
 echo ".. searching for \"$search_string\" in file: $file"
 grep -m1 "$search_string" $file
 if [ $? -eq 0 ]; then
 echo "successful - breaking the loop"
 break
 fi
 done
 
- 
				Nemohu za boha přijít na to jak grepem vrátit jen první výskyt v jednořádkovém vstupu. -m1 nepomáhá. Jde to řešit jinak než  přidáním |head -n1 ? Z výkonnostních důvodů
 
 skus -m 1 namiesto -m1?
- 
				Nemohu za boha přijít na to jak grepem vrátit jen první výskyt v jednořádkovém vstupu. -m1 nepomáhá. Jde to řešit jinak než  přidáním |head -n1 ? Z výkonnostních důvodů
 
 skus -m 1 namiesto -m1?
 
 Pouzitie -m1 alebo -m 1 da to iste, t.j. prvy najdeny vyskyt v jednom subore. To znamena, ze ak grep prehladava viac suborov tak ku kazdemu suboru v ktorom najde nejake vyskyty vypise prvy, co vo vysledku znamena ze grep moze vratit viac ako jeden riadok.
- 
				Dnes ty rady mi chodí uplně mimo, tak doplním zadání. Nepomohla ni první rada, nevrací mi to nic, upravil jsem to a zkusil přidat /gi flag nebo ubrat ^a$.
 
 - Charakter grepování vyžaduje  volbu -o - když je to jeden řádek přeci :
 - Taky ještě doplním/připomenu, že ten skript mi vrátí všechny výskyty (na co výskyt, to řádek) . Takže to |head -n1 řeší, jen je to pomalé.
 - Taky jsem hledal elegantní řešení,  přímo aktérující na příkazu grep, nějaký jeden switch, než to přepíšu do awk
 - Délka jednotlivých segmentů 40kB až 4MB, celková délka vstupu 300MB, ale tím tailem ji "seekuju" ..
 Fakt, že vstup je jednořádkový znamená, že nanajvýš může být v jednom souboru. Kdyby byl v nula souborech , tak by nebylo co vstupovat. Ve skutečnosti je ale vstup z pípy (protože jsou z souboru odstraněny některé znaky jako  \n \r a mezery).
 
 Přirozeně,  m mezera 1 nepomohlo.   :o Bohužel grep v tomhle má krev na rukou, protože volba se jmenuje --max-count, ale až man vysvětluje  vysvětluje, že se to týká řádků
 
 
 Zjednodušený zadání: ale bojím, se , že to bude moc dlouhý, na to jak to ve skutečnosti je jednoduchý
 
 Při každém použití  dávám různý parametr prvnímu příkazu tail, jde o append only soubor vstup.txt. Hledaný řetězec  začíná MAGIC (shodou okolností na začátku řádku, ještě před tr) a končí nějakým delimiterem . A rozprostírá se to přes víc řádků, proto ten mezikrok s tr.
 tail -n8000 vstup.txt |  tr -d "\r\n " |grep -Po "MAGIC[^-]......"
 
 vstup
 echo ' dfjkfjk skhd ;jkh kjdjfh --- skjdfh sd ;khsdskjfjh ;jh h;kh --- ;kjh --- ;kjh ;kjh ;k ;'  |grep -Po ";[^-]+"
 
 Prostě jednoduše: začíná to středníkem slovo a jede se až po první pomlčku. V tomhle vstupu jsou čtyri výsledky(=dá 4 rádky), já chci jen první, -m1 dá identický výstup.
 Pozor, středník může být i uvnitř a stejně tak pomlčka může být i mimo zachytávný region a nic neznamená
 
 jako mohou použít AWK asi(myslím, že na takovéhle výstřižky určené počátečním a koncovým patternem přímo umí, něco jako toggle a převzal to ruby |ruby -ne 'print if /StartToken/ ... /Konec/' ),  místo grepu, když to grep in-house neumí, doufal jsem ,že když -m1 nefunuje, že je nějaká analogogie jako -n1 když se neoperuje s řádky, ale s výskyty
- 
				Tak on ten sed i funguje, jen ten "or empty" ... "|()" musi byt na konci celeho vyrazu:
 
 $ echo 'halabalaregexfujkyneregex?' | sed -E 's/^(((.*)(regex)(.*))|(.*))$/\4/'
 regex
 $ echo 'halabalarugexfujkynerugex?' | sed -E 's/^(((.*)(regex)(.*))|(.*))$/\4/'
 
 $
 
 Samozrejme to vraci i prazdni radek, ne prazdny vystup.
 
 Skripty tohoto druhy opravdu nepisu v bashi, hlavne kdyz drobnost typu | head -n1 je vykonnosti problem.
 A i v PHP si vstup sekam na mensi elementy, nez provadet nejake operace nad MB daty.
- 
				
 vstup
 echo ' dfjkfjk skhd ;jkh kjdjfh --- skjdfh sd ;khsdskjfjh ;jh h;kh --- ;kjh --- ;kjh ;kjh ;k ;'  |grep -Po ";[^-]+"
 
 Prostě jednoduše: začíná to středníkem slovo a jede se až po první pomlčku. V tomhle vstupu jsou čtyri výsledky(=dá 4 rádky), já chci jen první, -m1 dá identický výstup.
 Pozor, středník může být i uvnitř a stejně tak pomlčka může být i mimo zachytávný region a nic neznamená
 
 
 
 tak nechapu proc mazes pres tr ty newlines, kdybys tam proved tr ";" "\n", tak si to muzes zpracovat skrze -m1 (stop after 1 matching line)
- 
				vstup
 echo ' dfjkfjk skhd ;jkh kjdjfh --- skjdfh sd ;khsdskjfjh ;jh h;kh --- ;kjh --- ;kjh ;kjh ;k ;'  |grep -Po ";[^-]+"
 
 
 skusil som cez awk:
 
 echo ' dfjkfjk skhd ;jkh kjdjfh --- skjdfh sd ;khsdskjfjh ;jh h;kh --- ;kjh --- ;kjh ;kjh ;k ;'  | awk 'BEGIN {RS="---"; FS=";"} {for(i=2; i<=NF; i++) printf(";%s",$i); print(""); exit}'
 
 vysledok:
 ;jkh kjdjfh
- 
				první výskyt v jednořádkovém vstupu
 
 
 grep -o -m1 word <<< $(echo 'First word, second word.' | grep -o word)