Fórum Root.cz

Hlavní témata => Software => Téma založeno: Ħαℓ₸℮ℵ ␏⫢ ⦚ 07. 02. 2024, 11:31:55

Název: Jen první výskyt z grep -o -P
Přispěvatel: Ħαℓ₸℮ℵ ␏⫢ ⦚ 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ů
Název: Re:Jen první výskyt z grep -o -P
Přispěvatel: RDa 07. 02. 2024, 17:18:37
co treba neco, co vrati vyraz dle patternu nebo taky nic, pokud tam neni:

Kód: [Vybrat]
sed -E 's/^(.*)((regex)|())(.*)$/\2/'
Název: Re:Jen první výskyt z grep -o -P
Přispěvatel: mikrom 07. 02. 2024, 21:02:29
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:
Kód: [Vybrat]
#!/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
Název: Re:Jen první výskyt z grep -o -P
Přispěvatel: e3k 07. 02. 2024, 21:17:35
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?
Název: Re:Jen první výskyt z grep -o -P
Přispěvatel: mikrom 07. 02. 2024, 23:16:36
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.
Název: Re:Jen první výskyt z grep -o -P / zadání doplněno
Přispěvatel: Ħαℓ₸℮ℵ ␏⫢ ⦚ 07. 02. 2024, 23:30:21
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
Název: Re:Jen první výskyt z grep -o -P
Přispěvatel: RDa 08. 02. 2024, 00:34:19
Tak on ten sed i funguje, jen ten "or empty" ... "|()" musi byt na konci celeho vyrazu:

Kód: [Vybrat]
$ 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.
Název: Re:Jen první výskyt z grep -o -P / zadání doplněno
Přispěvatel: RDa 08. 02. 2024, 00:37:45

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)
Název: Re:Jen první výskyt z grep -o -P / zadání doplněno
Přispěvatel: mikrom 08. 02. 2024, 01:27:19
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
Název: Re:Jen první výskyt z grep -o -P
Přispěvatel: Modulo 08. 02. 2024, 09:32:55
první výskyt v jednořádkovém vstupu

grep -o -m1 word <<< $(echo 'First word, second word.' | grep -o word)