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.
I am working on a project where I read incoming data from a RFID reader, and spit the data into a database. The data coming from the device looks like this:
My script reads this data into an array, splitting on the comma:
Code:
#!/usr/bin/perl -w
use strict;
use warnings;
use IO::Socket;
my $port = 4000;
my @data;
my $server = IO::Socket::INET->new (
Proto => 'tcp',
LocalPort => $port,
Listen => SOMAXCONN,
);
print "Server running on port $port...\n";
while (my $connection = $server->accept) {
print "Client connected at ", scalar(localtime), "\n";
while (<$connection>) {
@data = split (/,/);
print @data;
}
close $connection;
print "Client disconnected\n";
}
My problem is this: I *know* that I need only 6 fields in my array: tag, disc, last, count, ant and proto; however, the script doesn't allow me to define where an array stops and a new one begins. For example, I would like to do something like this:
my @data = $tag, $disc, $count...etc
So that when this part of the script reads:
Code:
while (<$connection>) {
@data = split (/,/);
print @data;
}
...it stops on the 6th field and creates a new array.
Is this making sense? All of the textbook examples have the array's data defined at the beginning of the script, which obviously isn't going to happen here; I need to insert the data as it comes in, and access it (so I can then insert it).
Help!
Thanks,
Josh
Last edited by hardbop200; 10-27-2008 at 09:36 PM.
Reason: added code tags
Actually, its not entirely clear to me, but I'll have a go.
Are you getting 6 fields at a time into the array, or 1 field at a time ie a 6-field rec, or an unending stream of individual fields, 1 at a time that happen to be csv?
What do you need to do with the data?
Are you going to process each array / 6-fields as they arrive, or are you planning to store a load of them and process them later?
PS please use code tags, it makes it easier to read your code.
A q&d way of doing this would be to have a counter that increases whenver you see the proto tag and push the data into an anonymous array in a hash
kind of like
Code:
$counter = 0;
while (<$connection>) {
@data = split(/,/);
foreach $item (@data) {
push @{$h_data{$counter}}, $item;
if ($item =~ /Proto: /) {
$counter++;
}
}
}
# counter ends up with the total number of records read
Now if it's a continuous stream then instead of just incrementing the counter you could call a function with the data, just make sure you delete the entry when your finished so you don't run out of memory.
Now if it's a continuous stream then instead of just incrementing the counter you could call a function with the data, just make sure you delete the entry when your finished so you don't run out of memory.
Thanks, I'll try all of these suggestions and see which one works out best.
You were right about the continuous stream; I'll give this approach a try and see if I can figure this out and I'll post my results.
Thanks for all of the information, and apologies for my post being a little hazy...I'm very new to Perl, just trying to use it to "get the job done!"
OK, lots of good stuff happening with this script!
Here's what ended up working:
Code:
while (my $data = <$connection>) {
foreach (split(/\n/,$data)) {
#print $data;
my ($field0, $field1, $field2, $field3, $field4, $field5) = (split(/\,/,$_))[0,1,2,3,4,5];
This returns nicely formatted columns like:
Code:
Tag:4845 4930 3030 3030 3030 3032
Now I would like to run each item ($field0, $field1, etc.) through another parser in a subroutine that will split each column by the colon ":", with the first part of the split being $key (which will be discarded), and $value (which will actually be inserted; Here is the part of the code that sends $field0...$field5 to the parser:
sub parse_text {
foreach (@_) {
my ($key, $var) = (split(/:/,@_))[0,1];
$var = @_;
return @_;
}
}
Basically, I want to send the parser $field0, split it, assign the result of $var = $field0, and return the new-and-improved $field0 back to my main program. Yet, the $var = @_ doesn't seem to work, and return @_ sure doesn't work. Any ideas?
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.