[BASH/SH] Regex/Rematching Problems

Hi anyone,
since Sunday I try to create a schellscript that reads the last 10 lines of text out of a log and parses the guid's of the entrys in there.
The log looks like this:

ClienUserinfo: ... \cl_guid\XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\...

i tried to parse it like this:

for line in $(tail -n 10 $log );
    do
        #is it a line we want to catch??
        if [[ $newline =~ [C][l][e][n][t][e][r][n][f][o][:] ]]; then
            #get the guid
            if [[ $newline =~ [c][l][_][g][d][\\](................................) ]]
            then
                  guid="${BASH_REMATCH[1]}"
                echo found guid
                echo $guid
            else 
                echo error, no guid
            fi
    done

This works only if the given guid in the logifle starts with a Letter, if the first Character is a number, it gets some wrong crap out.

I am looking forward to find help,
S0lll0s

PS: pls dont mess my code up so i dont understand it anymore, thx:)

Could you please provide and example of output of

tail -10 yourlogfile

and let us know what result you need

$ tail -10 file  | ruby -e 'while s=gets;puts s.gsub(/.*cl_guid\\(.*?)\\.*/,"\\1") if /ClienUserinfo/;end'
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX


How is $newline getting set in your script?

---------- Post updated at 11:03 AM ---------- Previous update was at 10:50 AM ----------

This seem to work OK for me:

Note:
Uses read -r to avoid \ processing
No need for all the [ and ] in match
No "t" in ClienUserinfo

tail -n 10 $log | while read -r
do
    #is it a line we want to catch??
    if [[ "$REPLY" =~ ClienUserinfo: ]]; then
        #get the guid
        if [[ "$REPLY" =~ cl_guid\\(................................) ]]
        then
            guid="${BASH_REMATCH[1]}"
            echo found guid
            echo $guid
        else
            echo error, no guid
        fi
    fi
done

thx all for the replys, will test it in next time!

---------- Post updated at 03:58 PM ---------- Previous update was at 06:57 AM ----------

@ctsgnb:
$newline loooks like this (if i want to use it):

2:35 ClientUserinfo: 0 \ip\localhost\name\test\racered\2\raceblue\2\rate\8000\ut_timenudge\0\cg_rgb\255 0 0\funred\gasmask,h_head\funblue\gasmask,h_head\cg_predictitems\0\cg_physics\1\gear\GZAARWA\cl_anonymous\0\sex\male\handicap\100\color2\5\color1\4\team_headmodel\*james\team_model\james\headmodel\sarge\model\sarge\snaps\20\teamtask\0\cl_guid\F6F1365D96239BB0C6BB7CE6A74C064B\weapmodes\00000110220000020002

any other lines dont contain ClientUserinfo

@ Chubler_XL
just misspelling, its "ClientUserinfo"
Somehow it doesnt work, it just reads a few lines, and a few it doesnt. also it doesnt read the whole line, it stops after a few lines.

tail -n 10 $log | while REPLY=read -r
do
    #is it a line we want to catch??
    if [[ "$REPLY" =~ ClienUserinfo: ]]; then
....

but it didnt work.

@Kurumi i dont get how i should read the variable now. I tried adding "print $s" at the end but it returned the whole last 10 lines.

Ooops

tail -10 yourlogfile | sed '/ClientUserinfo/!d;s/.*cl_guid\\//;s/\\.*//'
# cat tst
0
1
2
3
2:35 ClientUserinfo: 0 \ip\localhost\name\test\racered\2\raceblue\2\rate\8000\ut_timenudge\0\cg_rgb\255 0 0\funred\gasmask,h_head\funblue\gasmask,h_head\cg_predictitems\0\cg_physics\1\gear\GZAARWA\cl_anonymous\0\sex\male\handicap\100\color2\5\color1\4\team_headmodel\*james\team_model\james\headmodel\sarge\model\sarge\snaps\20\teamtask\0\cl_guid\F6F1365D96239BB0C6BB7CE6A74C064B\weapmodes\00000110220000020002
5
6
7
8
9
10
# tail tst | sed '/ClientUserinfo/!d;s/.*cl_guid\\//;s/\\.*//'
F6F1365D96239BB0C6BB7CE6A74C064B
#

I didn't write this, it was in RegExr as a saved expression. I suck at regex's but maybe it'll help you.

\{[0-9a-fA-F]{8}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{12}\}

The nice thing about the tool is that it will test your regex for you and has a bunch of saved regex's which is why I like it :smiley:

You can find it at, exploded link since I don't have 5 posts yet and can't post links.

gskinner dot com forwardslash RegExr

All the tools will never replace brain
Depending on where you are going to use it :

[0-9a-fA-F]{32}
[0-9a-fA-F]\{32\}
[[:xdigit:]]\{32\}

:smiley:

THX to ALL of you,
seems to work now!

---------- Post updated at 07:49 PM ---------- Previous update was at 07:44 PM ----------

next Problem :smiley:

tail -n 10 $log | sed '/ClientUserinfo/!d;s/.*cl_guid\\//;s/\\.*//' | while read
            do
                guid=$REPLY
            done
echo $guid

echoes nothing. I know it beacause of the var is a local one but export and set dont work somehow :frowning:

PS: I am on SH-3.2

try to put

echo $guid

inside the loop

...
do
     guid=$REPLY
     echo $guid
done

And see if something get displayed ...

also double quote around your variable "$guid"

... otherwise you can still go for

tail -n 10 $log | sed '/ClientUserinfo/!d;s/.*cl_guid\\//;s/\\.*//' | while read ans
            do
                guid="$ans"
            done
echo "$guid"

This works.

tail -n 10 $log | sed '/ClientUserinfo/!d;s/.*cl_guid\\//;s/\\.*//' | while read
            do
                echo "$REPLY"
            done
            echo "$REPLY"

echoes
"66F1365D96239BB0C6BB7CE6A74C064B
"
(nothing 2nd time)

if i do

tail -n 10 $log | sed '/ClientUserinfo/!d;s/.*cl_guid\\//;s/\\.*//' | while read
            do
                guid="$REPLY"
                export guid
                export
            done
            echo "$REPLY"

it showes this:
...
export __CF_USER_TEXT_ENCODING="0x1F5:0:3"
export guid="66F1365D96239BB0C6BB7CE6A74C064B"
but if i quit the script and type
"export"
guid isnt set again :frowning:

If you are sure that within the 10 last line of your log file, you will never get more than 9 guid, you can (and if your script has already saved $1 $2 ... arguments in some other variables you can just replace your whole loop with something like :

set -- `tail -n 10 $log | sed '/ClientUserinfo/!d;s/.*cl_guid\\//;s/\\.*//'`
echo "$*"

or

guid1=$1
guid2=$2
guid3=$3
...
guid9=$9
echo "guid1=${guid1} guid2=${guid2} ..."
sed: 1: "/ClientUserinfo/!d;s/.* ...": bad flag in substitute command: '\'

tried something like that before....

Here is an example with short ID just for demo purpose :

# tail -9 tst | awk '{print$2}'
199E
1BCC
0A9B
0AA1
15A5
15AD
0AA2
15A6
15AC
# echo $*

# set -- `tail -9 tst | awk '{print$2}'`
# echo $*
199E 1BCC 0A9B 0AA1 15A5 15AD 0AA2 15A6 15AC

guid=`tail -n 10 $log | sed '/ClientUserinfo/!d;s/.*cl_guid\\//;s/\\.//'`
produces this error:
sed: 1: "/ClientUserinfo/!d;s/.
...": bad flag in substitute command: '\'
and your last example never prints out ANYTHIN with tst =

199E
1BCC
0A9B
0AA1
15A5
15AD
0AA2
15A6
15AC

also

tail -n 10 $log | sed '/ClientUserinfo/!d;s/.*cl_guid\\//;s/\\.*//'
            echo $REPLY

prints out:
"66F1365D96239BB0C6BB7CE6A74C064B

"
(2nd line empy again) BUT WHY???

Could you please copy paste the whole command you entered ? (as far as i have tested, for me it works)

Ooops, yes of course, i called my test file "tst" but you should replace "tst" by the name of your logfile !!!!

s0lll0s:Desktop S0ll0s$ set -- `tail -9 tst | awk '{print$2}'`
s0lll0s:Desktop S0ll0s$ echo $*

s0lll0s:Desktop S0ll0s$ set -- `tail -9 tst | awk '{print$2}'`
s0lll0s:Desktop S0ll0s$ echo $*

s0lll0s:Desktop S0ll0s$ tail -9 tst | awk '{print$2}'

SOLVED:
guid=`tail -n 10 $log | sed '/ClientUserinfo/!d;s/.*cl_guid\\\//;s/\\\.*//'`
            echo $guid

had to triple the backslashes!
THXctsgnb!!

s0lll0s:Desktop S0ll0s$ tail -9 tst | awk '{print$2}'

s0lll0s:Desktop S0ll0s$ tail -9 tst | awk '{print$2}'

s0lll0s:Desktop S0ll0s$ tail -9 tst | awk '{print$2}'

[/CODE]while tst looks like:

199E
1BCC
0A9B
0AA1
15A5
15AD
0AA2
15A6
15AC

or try this replacing the back quote with $( ) notation

set -- $(tail $log | sed '/ClientUserinfo/!d;s/.*cl_guid\\//;s/\\.*//')

---------- Post updated at 08:42 PM ---------- Previous update was at 08:39 PM ----------

# log=tst
# echo $*

# cat tst
1
2:35 ClientUserinfo: 0 \ip\localhost\name\test\racered\2\raceblue\2\rate\8000\ut_timenudge\0\cg_rgb\255 0 0\funred\gasmask,h_head\funblue\gasmask,h_head\cg_predictitems\0\cg_physics\1\gear\GZAARWA\cl_anonymous\0\sex\male\handicap\100\color2\5\color1\4\team_headmodel\*james\team_model\james\headmodel\sarge\model\sarge\snaps\20\teamtask\0\cl_guid\F6F1365D96239BB0C6BB7CE6A74C064B\weapmodes\00000110220000020002
2:35 ClientUserinfo: 0 \ip\localhost\name\test\racered\2\raceblue\2\rate\8000\ut_timenudge\0\cg_rgb\255 0 0\funred\gasmask,h_head\funblue\gasmask,h_head\cg_predictitems\0\cg_physics\1\gear\GZAARWA\cl_anonymous\0\sex\male\handicap\100\color2\5\color1\4\team_headmodel\*james\team_model\james\headmodel\sarge\model\sarge\snaps\20\teamtask\0\cl_guid\I6F1365D96239BB0C6BB7CE6A74C064B\weapmodes\00000110220000020002
2:35 ClientUserinfo: 0 \ip\localhost\name\test\racered\2\raceblue\2\rate\8000\ut_timenudge\0\cg_rgb\255 0 0\funred\gasmask,h_head\funblue\gasmask,h_head\cg_predictitems\0\cg_physics\1\gear\GZAARWA\cl_anonymous\0\sex\male\handicap\100\color2\5\color1\4\team_headmodel\*james\team_model\james\headmodel\sarge\model\sarge\snaps\20\teamtask\0\cl_guid\JRF1365D96239BB0C6BB7CE6A74C064B\weapmodes\00000110220000020002
5
6
7
2:35 ClientUserinfo: 0 \ip\localhost\name\test\racered\2\raceblue\2\rate\8000\ut_timenudge\0\cg_rgb\255 0 0\funred\gasmask,h_head\funblue\gasmask,h_head\cg_predictitems\0\cg_physics\1\gear\GZAARWA\cl_anonymous\0\sex\male\handicap\100\color2\5\color1\4\team_headmodel\*james\team_model\james\headmodel\sarge\model\sarge\snaps\20\teamtask\0\cl_guid\K6F1365D96239BB0C6BB7CE6A74C064B\weapmodes\00000110220000020002
9
10
# set -- $(tail $log | sed '/ClientUserinfo/!d;s/.*cl_guid\\//;s/\\.*//')
# echo $*
F6F1365D96239BB0C6BB7CE6A74C064B I6F1365D96239BB0C6BB7CE6A74C064B JRF1365D96239BB0C6BB7CE6A74C064B K6F1365D96239BB0C6BB7CE6A74C064B
#

---------- Post updated at 08:44 PM ---------- Previous update was at 08:42 PM ----------

NOTE: by default, tail only takes the 10 last line so you don't need to specify -n 10

assign it to a variable

variable=$(tail -10 file  | ruby -e 'while s=gets;puts s.gsub(/.*cl_guid\\(.*?)\\.*/,"\\1") if /ClienUserinfo/;end')

this you should have already learned in basic unix scripting.