Operating System - Linux
1824874 Members
3792 Online
109674 Solutions
New Discussion юеВ

Using PErl to loop through a file

 
Steve_617
Advisor

Using PErl to loop through a file

I am trying to loop through a file with perl.
The file consists of hundreds of lines, with records that begin with
_obj_id: alarmRecordId I 340
and ends with
_end_block:
Well that is the range of each record that I want.
However the portion that starts with block and ends with end_block is in more than one line, and that is where I am getting stumped.

I feed each line into the array. When I get to the block portion I have no idea how to tackle it. A sample of the file is attached.

I need to output in a flat file format where each record will be converted to a one line.

Typical Output for first record
alarmRecordId = 340: COMPID = NI EM MP2RPB01 LP 5 E1 3: severity = E critical: commentData S Loss of Frame condition has been detected (dl1LofAlarm). Check the statistics attributes and configuration of the far-end.

This should be in one line from the 1st record provided in the tmp1 file
Can anyone help

Regards
Steve
8 REPLIES 8
Simon Hargrave
Honored Contributor

Re: Using PErl to loop through a file

I'm not 100% sure on your requested output because it appears you miss some bits out, however to extract it all should be very easy in awk (not sure about perl but if this is all you need to do awk is nicer): -

awk -F: 'BEGIN { str="" }
block == 1 { str = str$1 }
$1 == "_obj_id" { str = str$2 ; block = 0 }
$1 == "_attr" { str = str" : "$2 }
$1 == "_block" { block = 1 ; str = str" : "$2 }
$1 == "_end_block" { print str"\n" ; str = "" }
' yourfile

This should give you a start.
H.Merijn Brand (procura
Honored Contributor

Re: Using PErl to loop through a file

make "_end_block:\n" the record separator

--8<---
open my $file, "< file.xxx" or die "file.xxx: $!\n";
local $/ = "_end_block:\n";
while (<$file>) {
# process the block
}
close $file;
-->8---

Enjoy, Have FUN! H.Merijn
Enjoy, Have FUN! H.Merijn
Ralph Grothe
Honored Contributor

Re: Using PErl to loop through a file

Apart from localizing the input record separator you could also use the "..." operator in a pattern match.

e.g. in your parsing loop

while () {
if (/^_block/.../^_end_block/) {
# do something on matched line
}
}


If the files you parse are exceptionally large I would strongly dissuade you from pushing their contents in an array, as it consumes too much memory.
Better operate on the content linewise as in the example given by procura.

Madness, thy name is system administration
Steve_617
Advisor

Re: Using PErl to loop through a file


But if I loop through a file line by line, how can the I use the separator block, as each line is read in a new array.
I am not sure how you would use the block portion as a separator.

Regards

steve
H.Merijn Brand (procura
Honored Contributor

Re: Using PErl to loop through a file

using $/ as a input record separator, you are not reading the file line by line anymore, but block by block. Each block consists of lines

local $/ = "_end_block:\n";
while (<>) {
my @lines = split m/\n+/, $_;
# process line by line in block
foreach my $line (@lines) {
# these are the single lines
}
}

Enjoy, Have FUN! H.Merijn
Enjoy, Have FUN! H.Merijn
Ralph Grothe
Honored Contributor

Re: Using PErl to loop through a file

Sorry for increasing your confusion.
As for procura's example I should of course have correctly said blockwise instead of linewise.
But comparing the No. of bytes per block compared to the whole file, that's still more resource friendly.
Madness, thy name is system administration
Steve_617
Advisor

Re: Using PErl to loop through a file

I hope I am not complicating issues, but looking at hashes (which I have never used before), is there a way I can send that file to a hash, where each first _keyword becomes the key-value. IE
_obj_class: alarmRecord
_obj_id: alarmRecordId I 340
_attr: time D 2005 07 05 13 54 46
_attr: compId NI EM MP2RPB01 LP 5 E1 3
_attr: rawState E OOS
_attr: compCriticality I 40
_attr: alarmType E communications
_attr: faultCode S 70115000
_attr: severity E critical
_attr: probableCause E lossOfFrame
_attr: notificationId I 83886094
_attr: originatorClass E passport
_attr: active I 1
_attr: customerId I 0
_attr: event E set
_block: _attr commentData S
Loss of Frame condition has been detected (dl1LofAlarm).
Check the statistics attributes and configuration of the far-end.


SO THAT I CAN CALL EACH KEY-VALUE BY NAME.
WOULD THIS BE POSSIBLE.


H.Merijn Brand (procura
Honored Contributor

Re: Using PErl to loop through a file

local $/ = "your block sep";
while (<>) {
my %hash = (/^(\w+):\s*(.*)/mg);
# $hash{_obj_id} = "alarmRecordID I 340"
}

Simple enough?

Enjoy, Have FUN! H.Merijn
Enjoy, Have FUN! H.Merijn