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)