ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
Hello,
I am trying to make a perl script which reads data from a file and parse it. The data in the file has the following syntax
Code:
Device Physical Name : Not Visible
Device Symmetrix Name : 1234
Device Serial ID : N/A
Attached BCV Device : N/A
Attached VDEV TGT Device : N/A
Device Capacity
{
Cylinders : 5120
Tracks : 76800
512-byte Blocks : 10485760
MegaBytes : 5120
KiloBytes : 5242880
}
Device Physical Name : Not Visible
Device Symmetrix Name : 4567
Device Serial ID : N/A
Device Capacity
{
Cylinders : 5120
Tracks : 76800
512-byte Blocks : 10485760
MegaBytes : 5120
KiloBytes : 5242880
}
Each unique record starts with "Device Physical Name". So, I have a set of records within "Device Physical Name". I want to read this set of records starting from "Device Physical Name" and ends up till next "Device Physical Name".
Offcourse FS is ":", and I just want to print/or later put info in a csv file. Would appreciate if I can get any help.
Ok I see where you are going If you search around you will see a common way of reading from a file is as follows:
Code:
open(HANDLE, "file_name") || die "couldn't open the file!";
while($line = <HANDLE>){ # This is also seen a lot as while(<HANDLE>) but you can look that up
print $line;
}
close(HANDLE);
Obviously you can split and do other thing other than print.
Are the contents of the file in uniform? It looks like that its main delimeter is a blank line. In awk that can be easily achieved with RS = "" and FS = ":". But I'm interested to learn hacking this in Perl.
Edit: I think FS = ":" won't do. But anyway, how do you intend to save the values in csv?... Noting that some items have more parameters than the other: Attached BCV Device, Attached VDEV TGT Device..
Last edited by konsolebox; 08-21-2010 at 06:45 AM.
Are the contents of the file in uniform? It looks like that its main delimeter is a blank line. In awk that can be easily achieved with RS = "" and FS = ":". But I'm interested to learn hacking this in Perl.
Edit: I think FS = ":" won't do. But anyway, how do you intend to save the values in csv?... Noting that some items have more parameters than the other: Attached BCV Device, Attached VDEV TGT Device..
The contents of the file are all uniform. None of the item value is empty. In csv, the first field will become the item heading. For example, list all Devices with their size, and rest of the properties/info. Each item will become 1 heading, and each heading will have more than 1 values.
Ok I see where you are going If you search around you will see a common way of reading from a file is as follows:
Code:
open(HANDLE, "file_name") || die "couldn't open the file!";
while($line = <HANDLE>){ # This is also seen a lot as while(<HANDLE>) but you can look that up
print $line;
}
close(HANDLE);
Obviously you can split and do other thing other than print.
See if that helps?
Reading the file not a problem, how can I process a block of information while that block may or may not have a certain number of lines. 1 block may have 10 lines, other have 14.
If we do a split,
Code:
my @arr=split("\:",$line);
, the first element of the array brings all the values instead of just one.
The contents of the file are all uniform. None of the item value is empty. In csv, the first field will become the item heading. For example, list all Devices with their size, and rest of the properties/info. Each item will become 1 heading, and each heading will have more than 1 values.
Goni
Honestly I can't parse it. Can you give us an example output with the headers(?) of what you intend... At least based from the two entries. I think it can really make things clearer. You can place comments using # if you like.
Ok, here is what the sample output would look like, CSV output.
Code:
Device Physical Name,Device Symmetrix Name,Symmetrix ID.....
Not Visible,1234,1234567
Not Visible,3456,1234567
Not Visible,8726,1234567
Not Visible,0000,1234567
Not Visible,1234,1234567
Well basing from that and from the two entries you can get output like this:
Code:
Not Visible,1234,N/A,N/A,N/A,5120,76800,10485760,5120,5242880
Not Visible,4567,N/A,5120,76800,10485760,5120,5242880
Notice the difference in the number of columns they have.
Which could only mean that you need to parse the file in a more XML-like way. Not just linear. With this the possible attributes that may occur should first be predetermined.
I would suggest letting Perl do the first level of disassembly of the file, by using the blank line as a record delimiter:
Code:
$/="\n\n";
Having done that, each scalar read from the file will be a block of data, which can readily be split (hint) on newlines. From there, it looks pretty easy to create a hash of field names/values by splitting on ':'s.
Device Physical Name
Device Symmetrix Name
Device Serial ID
Attached BCV Device
Attached VDEV TGT Device
Device Capacity # ignored
Cylinders
Tracks
512-byte Blocks
MegaBytes
KiloBytes
No, there are some additional. But they are all with same FS. I think if it works for 2, it will work for all.
grail, it depends on what is the definition of a noob you got in your dictionary but, your code seems looping each item more than 1 times. I tried it, yet to debug, give an output 86 times with "Device Physical Name" suppose to show only 4 times
@Goni It's really important to determine all the possible attributes first since the code will depend on it. If you know the possible attributes, you can already determine where to place the values and where to reserve places for null values like with the example before:
Code:
Not Visible,1234,N/A,N/A,N/A,5120,76800,10485760,5120,5242880
Not Visible,4567,N/A,5120,76800,10485760,5120,5242880
You can expect an output like this instead
Code:
Not Visible,1234,N/A,N/A,N/A,5120,76800,10485760,5120,5242880
Not Visible,4567,N/A,,,5120,76800,10485760,5120,5242880
With that the code will be simpler since you don't have to collect all of the headers (attributes) and data first then dynamically create an order based from the collected headers, then print the data.
With the simpler version you can immediately print the data for each entry since you already know the order and where to reserve the null values.
If it can't be determined then there's no choice but to create the harder code.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.