We help IT Professionals succeed at work.

How to split log file lines into array with curly brackets and quotes as the delimiter

W00dyW00d
W00dyW00d asked
on
I have a log file that uses this type of format.  The there is a bunch of different line format this one example is from LINE_TYPE:  it is split by either { } or " " and sometimes there is { {} {} }, curly inside of curly.  I want to split all of them and put them into an array or maybe a hash with their variable name as a reference.  I can change the variable reference parts but I cant change the log file. This is just a short example most lines can get to a hundred variables.

LOG LINE:
Tue Jan 29 06:23:49 2008 LINE_TYPE: {test test} {3} {test} { {test1} {test2} } {files.doc} "testing again"

Then I have a variable that tells how to process "LINE_TYPE"
"LINE_TYPE:"  "%num1 %num2 %num3 %num4 %num5 %num6"


Thanks for the help!
Comment
Watch Question

ozo
CERTIFIED EXPERT
Most Valuable Expert 2014
Top Expert 2015

Commented:
How are we to interpret "LINE_TYPE:"  "%num1 %num2 %num3 %num4 %num5 %num6" ?
Are %num1 %num2 etc. the hash keys  for which you want to get the values from
Tue Jan 29 06:23:49 2008 LINE_TYPE: {test test} {3} {test} { {test1} {test2} } {files.doc} "testing again" ?
If so, what would go in $hash{'%num1'} and what would go in $hash{'%num2'} ?
What are the variable reference parts that you can change?

Author

Commented:
yes i was thinking maybe go into hash

"LINE_TYPE:"  "%num1 %num2 %num3 %num4 %num5 %num6"

so like

%LINE_TYPE = ( '%num1', '', '%num2', '', '%num3', '', '%num4', '', '%num5', '', '%num6', '' );

$LINE_TYPE{"%num1"} = "test test"
$LINE_TYPE{"%num2"} = "3"
$LINE_TYPE{"%num3"} = "test"
$LINE_TYPE{"%num4"} = "{test1} {test2}"
$LINE_TYPE{"%num5"} = "files.doc"
$LINE_TYPE{"%num6"} = "testing again"

Thanks for the quick reply!

Author

Commented:
sorry maybe the %num1 were confusing

i can use this instead...

%LINE_TYPE = ( 'num1', '', 'num2', '', 'num3', '', 'num4', '', 'num5', '', 'num6', '' );


Thanks!
CERTIFIED EXPERT
Most Valuable Expert 2014
Top Expert 2015
Commented:
Maybe you want  something like
$variable='"LINE_TYPE:"  "%num1 %num2 %num3 %num4 %num5 %num6"';
@keys = $variable=~/(%\w+)/g;


$_ = 'Tue Jan 29 06:23:49 2008 LINE_TYPE: {test test} {3} {test} { {test1} {test2} } {files.doc} "testing again"
';
@hash{@keys} = /{([^{}]*)}/g;


which would produce
%hash=(
   '%num1' => 'test test'
   '%num2' => 3
   '%num3' => 'test'
   '%num4' => 'test1'
   '%num5' => 'test2'
   '%num6' => 'files.doc'
);
but ''test test' does not look like a num to me

Author

Commented:
wow thanks, almost works one issue is the part where there is { {test1} {test2} } i want to put into one var

so when i run i get this
%num1 => test test
%num2 => 3
%num3 => test
%num4 => test1
%num5 => test2
%num6 => files.doc

so some are missing ... i want like this

%num1 => test test
%num2 => 3
%num3 => test
%num4 => {test1} {test2}
%num5 => files.doc
%num6 => "testing again"

Yea num was just a quick var i wrote up they will be renamed later

Thanks
Top Expert 2009
Commented:
Try this change to ozo's code:

@hash{@keys} = /[\{"]\s*(\{.*?\}|.*?)\s*[\}"]/g;

Open in new window

ozo
CERTIFIED EXPERT
Most Valuable Expert 2014
Top Expert 2015

Commented:
($re=$_)=~s#((\{)|(\})|.)#${[')','']}[!$3]\Q$1\E${['(','']}[!$2]#gs;
$re=join"|",map{quotemeta}(eval{/$re/});
die $@ if $@;
@hash{@keys} = grep defined,/{($re)}|"([^"]*)"/g;

Author

Commented:
wow thanks guys Adam314 change fixed it.  ozo your latest change kept spaces.

Adam314:

%num3 => test
%num2 => 3
%num6 => testing again
%num5 => files.doc
%num1 => test test
%num4 => {test1} {test2}


ozo with latest changes

%num3 => test
%num2 => 3
%num6 => testing again
%num5 => files.doc
%num1 => test test
%num4 =>  {test1} {test2}


Thanks to both of you works great!!!

Author

Commented:
Thanks for all your help. I really appreciate it.

Explore More ContentExplore courses, solutions, and other research materials related to this topic.