LinuxQuestions.org
Download your favorite Linux distribution at LQ ISO.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 07-07-2016, 02:39 PM   #1
jmgibson1981
Senior Member
 
Registered: Jun 2015
Location: Tucson, AZ USA
Distribution: Debian
Posts: 1,140

Rep: Reputation: 392Reputation: 392Reputation: 392Reputation: 392
Perl syntax and my lack of knowledge.


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.
 
Old 07-07-2016, 03:10 PM   #2
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 10,006

Rep: Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191
Well I am no perl guru, but I have 2 suggestions:

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)
 
Old 07-07-2016, 06:36 PM   #3
keefaz
LQ Guru
 
Registered: Mar 2004
Distribution: Slackware
Posts: 6,552

Rep: Reputation: 872Reputation: 872Reputation: 872Reputation: 872Reputation: 872Reputation: 872Reputation: 872
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

Straight from example in:
http://perldoc.perl.org/perlop.html#...Like-Operators

Code:
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

Last edited by keefaz; 07-07-2016 at 07:07 PM.
 
Old 07-08-2016, 04:51 AM   #4
keefaz
LQ Guru
 
Registered: Mar 2004
Distribution: Slackware
Posts: 6,552

Rep: Reputation: 872Reputation: 872Reputation: 872Reputation: 872Reputation: 872Reputation: 872Reputation: 872
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/;
    }
}
 
Old 07-08-2016, 07:27 AM   #5
sundialsvcs
LQ Guru
 
Registered: Feb 2004
Location: SE Tennessee, USA
Distribution: Gentoo, LFS
Posts: 10,659
Blog Entries: 4

Rep: Reputation: 3939Reputation: 3939Reputation: 3939Reputation: 3939Reputation: 3939Reputation: 3939Reputation: 3939Reputation: 3939Reputation: 3939Reputation: 3939Reputation: 3939
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.
 
Old 07-08-2016, 10:19 AM   #6
jmgibson1981
Senior Member
 
Registered: Jun 2015
Location: Tucson, AZ USA
Distribution: Debian
Posts: 1,140

Original Poster
Rep: Reputation: 392Reputation: 392Reputation: 392Reputation: 392
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 <>.
 
Old 07-08-2016, 11:16 AM   #7
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 10,006

Rep: Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191
You could target the From at the start of the line with anchor and then store the data between the <> with grouping.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
perl: Context or Syntax merana Programming 4 12-08-2009 12:17 AM
Lack of Networking Knowledge to get a Linux machine on a network. Sir Meowdengalf Linux - Networking 5 05-17-2006 04:36 PM
Trouble printing raw from browser (maybe my lack of bash knowledge) karlmdv Linux - General 0 03-08-2005 06:53 PM
Paranoia due to lack of knowledge downinthemine Linux - Security 2 12-04-2003 12:37 AM
perl syntax jenny_psion Programming 2 08-13-2003 12:23 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 01:31 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration