[Megoldva] Regex kérdések

1. Adott az alábbi sor:


TEST 12345.123 17.01.2021 More text 12345

Ebből szeretném kivenni az első szóköz utáni számot a .-ig.

Az alábbi regex ezt kiszedi, de nekem maga a számra lenne szükségem (12345).


sed "s/\ [^\.]*//"

Hogy lehet ezt negálni?

És a dátumot hogy tudom kiszedni ebből? A formátum kötött, tehát nem változik.

2. Egy adott fájlban rákeresek egy stringre amit szépen megkapok és az utána következő második sorra lenne szükségem. A grep -A 2 megadja a sorokat és ott van az utolsó sor ami kell, de ezt kellene leválogatnom. Lehet triviális, nekem nem az.

Köszönöm előre is a segítséget.

Úgy tanul az ökör ha tanítják :-)

Megoldás:
egeresz fórumtárs awk-os megoldásai a legjobbak, de a többit is jegyeztem az eddigiek mellé :-)

Hozzászólások

1.
echo "TEST 12345.123 17.01.2021 More text 12345" | sed 's/^[A-Z]\+ \([0-9]\+\)\..*$/\1/'
A \( \) közti részt a regexp elmenti, \1-ként hivatkozhatsz rá a cserében.
Ha akarod, akkor ketté is szedheted amúgy…
echo "TEST 12345.123 17.01.2021 More text 12345" | sed 's/^[A-Z]\+ //' | sed 's/\..*$//'

2.
A tail -n1 az előző parancs utolsó sorát adja vissza, szerintem arra van szükséged. Ez csak akkor megy, ha egyszer fordul elő, egyébként minden harmadik sorra van szükséged, amihez nekem is kapcsolódik dilemmám: van valami kulturált mód az ennedik sor visszaadására? Eddig egymásba szoktam pipe-olni egy headet meg egy tailt, de ezt korlátozottan kulturált megoldásnak tartom…☺)
Ha több találat van, arra szerintem az awk nyújt megoldást, amihez nem értek. Meg lehet kerülni, de az nagyon csúnya:
t = $(tempfile)
lines = $(wc -l $t)
grep -A 2 pattern file >> $t
for i in `seq 3 4 $lines`; do tail -n $i $t | head -n 1; done
… vagy valami ilyesmi, nem teszteltem, és ha van épkézláb megoldás, inkább használd azt… ☺

int getRandomNumber() { return 4; }  // ← aláírás
//szabályos kockadobással választva. garantáltan véletlenszerű.  xkcd

Jogos.

És legyen itt mementónak az adott sorszámú sor, ami nyilván erősen UTFG kérdés volt részemről:
http://stackoverflow.com/questions/1429556/shell-bash-command-to-get-nt…
… és külön tetszik a minden ennedik sorra ez a perles megoldás:

… | perl -n -e 'if ($. % 7 == 0) { print; }'
int getRandomNumber() { return 4; }  // ← aláírás
//szabályos kockadobással választva. garantáltan véletlenszerű.  xkcd

a mondás így van: akkor tanul a gyerek, ha kérdez.

asd@locutus:~$ echo TEST 12345.123 17.01.2021 More text 12345 | sed "s/[^ ]*\ \([^.]*\)\..*/\1/"
12345

Megjegyzes: karakterosztalyban (ertsd: [ es ] kozott) nem szabad escapelni, mert a [\.] egesz pontosan \ VAGY . karaktert jelent.

Ha az adatok ilyen szerkezetűek, tehát nem a szám a lényeg, hanem a szóköz meg a pont, akkor így is lehet:

cut -d' ' -f2 <<<'TEST 12345.123 17.01.2021 More text 12345' | cut -d. -f1

tr [:lower:] [:upper:] <<<locsemege
LOCSEMEGE

Vagy egy perverz megoldás awk-val:

awk '{printf("%d\n", $2); }' <<<'TEST 12345.123 17.01.2021 More text 123456'

tr [:lower:] [:upper:] <<<locsemege
LOCSEMEGE

1
Mire kell neked az a szam.
Pl kiirni? Shell helyett AWK-ban

awk '{ print int($2) }'

Vagy kell a datum, es utana ez a szam?

awk '{ print $3, int($2) }'

Az AWK -nak kis programot adsz at parameterben, amit az ertelmez es lefuttat.
Legegyszerubb esetben minden sorra lefutatja az altalad megadott kis programot.
Space/tab alapjan szetvalasztja az input sort, es a mezoket berakja a $1, $2, $3.. stb-be.
Pontot hasznal tizedes szeparatornak. Az egesz input sor a $0.

2
Mit csinalsz az utana kovetkezo masodik sorral? Kiirod?

awk '/erre keress ra/{ getline; getline; print $0 }'

Ez mar bonyibb AWK program, mert ez nem minden sorra fut le, csak azokra, amik illeszkednek a stringre. Utana kezzel (getline fuggveny) lepsz kettot az input sorban, es
az igy kapott sort irod ki.

Az egysoros awk programokat nehez megverni sebessegben.

"És a dátumot hogy tudom kiszedni ebből?"

echo "TEST 12345.123 17.01.2021 More text 12345"|sed -n 's/^.* \([0-9]\{1,2\}\)\.\([0-9]\{1,2\}\)\.\([0-9]\{4\}\) .*/\3.\1.\2/p'

Igaz. Bár valamiért az az érzésem, a More text általános, a TEST pedig konkrét minta. Nem tudom, miért...

Ekkor még lehetne a

grep -Eo '([[:digit:]]{2}\.){2}[[:digit:]]{4}'<<<'TEST 12345.123 17.01.2021 More text 12345'

is jó megoldás.

tr [:lower:] [:upper:] <<<locsemege
LOCSEMEGE