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.
New job requires me to learn perl. They've given me an assignment to write a little script so here is where i am so far.
Code:
#!/usr/local/bin/perl
use strict;
use warnings;
# patterns
my @patterns = (
# source
"",
# target
"",
# reason for failure
""
);
# open files
open(INPUT, "<$ARGV[0]");
open(OUTPUT, ">>ARGV[1]");
# main loop
foreach my $patterns (@patterns) {
while (my $line = <INPUT>) {
if ($line = $patterns) {
print OUTPUT $line;
}
}
}
# close files
close(INPUT);
close(OUTPUT);
The goal of this script is to iterate through the patterns array, which will contain regular expressions. then for each of those patterns search through a text file and find it, then assign the found pattern to a variable. finally print a line to a logfile with each found pattern in a certain order.
This is my second day working with perl so I have a long way to go. Like posted, this is what I have so far. Right now I'm having trouble trying to get it to output to the logfile (ARGV[1])
Any guidance or suggestions on methodology would be appreciated.
1. I am not a fan of naming different types of data (in your example scalar and array) with the same name. I do follow that with $ or @ at the start it is kind of clear, but it can get confusing in large scripts to be forced to always look for these (IMHO)
2. Why not start simple and just do the single open for the output and write a single line to it (I am sure there will be millions of returns in your search engine on how to do this)
There is a typo in OUTPUT, ">>ARGV[1]", should be OUTPUT, ">>$ARGV[1]"
Instead of looping through the patterns and the file lines, just use grep function like
Code:
#!/usr/local/bin/perl
use strict;
use warnings;
# patterns
my @patterns = (
# source
'something',
# target
'bla$',
# reason for failure
'^thing'
);
# open files
open(INPUT, "<$ARGV[0]") or die "$!\n";
open(OUTPUT, ">>$ARGV[1]") or die "$!\n";
# main loop
while (my $line = <INPUT>) {
print OUTPUT $line if grep {$line =~ /$_/ } @patterns;
}
close INPUT;
close OUTPUT;
Edit, it could be interesting to compile patterns to gain some speed
my @patterns = (...);
my @compiled = map qr/$_/, @patterns;
#then use @compiled instead of @patterns with grep
while (my $line = <INPUT>) {
print OUTPUT $line if grep {$line =~ $_} @compiled;
If patterns list or input text is long, you may better write a match function like in the linked example to avoid unecessary regexp match processing
Well, I am not satisfied with my grep suggestion. There is no way to stop grep after a match is sucessful, so it continues to check matches through the @patterns/@compiled array even if it founds a match. Grep function does not provide boolean result after all its purpose is to change an array into another.
Just a basic for loop will do, and exit this loop if match is found
Code:
while (<INPUT>) {
for my $pat(@patterns) {
print OUTPUT and last if /$pat/;
}
}
For instance, foreach my $patterns (@patterns) ... You should not be using the same variable-name here.
Perl is all about various characters such as '$', '@', '%', which are quite powerful but which can have unexpected side-effects. It's actually a tiny language compared to monsters like PHP, because it relies heavily on external modules (use ...).
Also: since you find yourself "in a Perl shop," be sure to ask your co-workers questions freely. Likewise your boss! Perl is a nice language but it has a substantial learning curve at first. Don't feel ashamed to ask "stupid" questions. (The only stupid question is the one you wouldn't ask.)
Take a look at existing source-code. You should be surrounded by it now.
And, while it's okay to ask for help on a forum like this, don't go here for substitutes to the assigned task of confronting the learning-curve yourself. That's what your new employer has tasked you to do ... and, they know that you can and will do it ... and you have the full sympathy and patient understanding of everyone. (There, and certainly here.)
Perl, quirky though it is, has been called "the Swiss ArmyŽ Knife of pragmatic computer programming," and with good reason.
Oh, yeah, one more thing: "meet Tim Toady," if you haven't yet. TMTOWTDI = There's More Than One Way To Do It.™
Last edited by sundialsvcs; 07-08-2016 at 07:34 AM.
I rewrote it for a if / elsif to find the 3 conditions i was looking for. It works now. Just one regex away from putting it into production. Any suggestions on a perl regex to match a line like this?
Code:
From: "Name of Letter" <email@address.com>
Specifically I'd like to extract the email@address field without the leading and trailing <>.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.