Welcome to WebmasterWorld Guest from 54.166.46.226

Forum Moderators: coopster & jatar k & phranque

Message Too Old, No Replies

Perl script to return a specific line of a file?

look at this!

   
6:55 pm on Jan 18, 2004 (gmt 0)

10+ Year Member



How could one make a program in Perl that, once called with one argument (a phone number, no spaces/dashes/slashes in it), look at a plain text file of the form

012345678901 Given-Name Lastname
123459012 Given-Name2 Lastname2

and get exactly that line that phone number matches the argument, and return it to the command line or as HTML? If no line matches, it should return the argument (the given number).

Sorry, I am a Perl rookie...

8:26 pm on Jan 18, 2004 (gmt 0)

10+ Year Member


Hi Mathis,
and welcome to WebmasterWorld.

The following perl program should do what you want:

#!/usr/bin/perl -w
#
# this pgm looks for argument ($ARGV[0]) in file $infile
# and prints all lines matching

$infile = "phonelist.txt";
$pattern = $ARGV[0]; # some more checking of argument should be done in here
$found = 0;

open(INPUT, $infile) ¦¦ die "Error opening $infile : $!\n";

while(<INPUT>) {
if (/$pattern/) {
print;
$found += 1;
# exit; # put the exit here, if only the first match is required
}
}
if ($found == 0) {
print "Unfortunately, " . $pattern . " could not found.\n";
}
close(INPUT);

__END__

[In case you see a? before "die" in the open statement: it should be 2 vertical bars, which got mangled]

Good reading: the famous "camel"-book (Programming Perl -- by Larry Wall).

HTH and regards,
R.

10:51 pm on Jan 18, 2004 (gmt 0)

10+ Year Member



Thanks a lot! I will test it tomorrow, it should run on a FLI4L isdn+dsl router which has Perl installed. Take a look at fli4l.de/e_index.htm if you want to know about it... Quick and easy Linux installation for routing services. Every time a phone call comes in I will call the requested program with the number as argument and this will put a line in a log file on which I have half an eye on my desktop (tick-a-stat), so I can say "Hi <put in name>" when someone calls me... Quite funny.

[edited by: jatar_k at 4:31 pm (utc) on Jan. 19, 2004]
[edit reason] delinked [/edit]

10:54 pm on Jan 18, 2004 (gmt 0)

10+ Year Member



One single question: How can I print just the name? I need to cut off everything on the line from the file up to and including the first blank!
11:27 pm on Jan 18, 2004 (gmt 0)

10+ Year Member



... hmm, you really should get that camel-book ...

You may insert a simple regexp substitution (drop anything up to the first whitespace) as follows:
while(<INPUT>) {
if (/$pattern/) {
s/.*?\s//;
print;

HTH and regards,
R.

4:55 pm on Jan 19, 2004 (gmt 0)

10+ Year Member



It doesn't work!

Here's my script:

#!/usr/bin/perl -w
#
# this pgm looks for argument ($ARGV[0]) in file $infile
# and prints all lines matching

$infile = "phonelist.txt";
$pattern = $ARGV[0]; # some more checking of argument should be done in here
$found = 0;

open(INPUT, $infile)? die "Error opening $infile : $!\n";

while(<INPUT>) {
if (/$pattern/) {
s/.*?\s//;
print;
$found += 1;
exit; # put the exit here, if only the first match is required
}
}
if ($found == 0) {
print $pattern . "\n";
}
close(INPUT);

__END__

And the output:

# ./number2name.pl 01234567
Backslash found where operator expected at ./number2name.pl line 14, near "s/.*?\"
(Might be a runaway multi-line? string starting on line 10)
syntax error at ./number2name.pl line 14, near "s/.*?\"
Substitution replacement not terminated at ./number2name.pl line 14.

I run Perl 5.005_03...

Thanks!

5:25 pm on Jan 19, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



>open(INPUT, $infile)? die...

As Romeo mentioned, the forum software 'mangles' the pipe symbol. You need to change the? in the above line to two pipe symbols (vertical lines) and all should be okay.

6:12 pm on Jan 19, 2004 (gmt 0)

10+ Year Member



As Romeo mentioned, the forum software 'mangles' the pipe symbol. You need to change the? in the above line to two pipe symbols (vertical lines) and all should be okay.

Or, use use "or":

open FOO, "foo" or die;

It's also lower on the evaluation order totem pole, so if the left hand side ends up being a compound statement in the future, you won't run into problems.

Sean

6:25 pm on Jan 19, 2004 (gmt 0)

10+ Year Member



I hope this is ok to post, there is an undocumented UBB code that should help to avoid the smileys in perl code snippets:

put your snippet between
[ perl ] and [ /perl ]
without the spaces. It also adds syntax colouring. Doesn't help the pipes issue though. Example below.

[perl]
foreach $item(@array){
print "hello world, smile :)";
}
[/perl]

9:31 pm on Jan 20, 2004 (gmt 0)

10+ Year Member



Hey guys, you finally made it! I would be lost without your help. I thought it would be nice to post the complete thing if someone stumbles on this page later...

phonebook.txt has the following format:
012345824=Given Name Lastname
04385639=Name2 Whatever
...

and number2name.pl looks like this:
[perl]
#!/usr/bin/perl -w
#
# this pgm looks for argument ($ARGV[0]) in file $infile

$infile = "phonebook.txt";
$pattern = $ARGV[0]; # some more checking of argument should be done in here
$found = 0;

open(INPUT, $infile) die "Error opening $infile : $!\n";

while(<INPUT>) {
if (/$pattern/) {
s/.*?=//;
print;
$found += 1;
exit; # put the exit here, if only the first match is required
}
}
if ($found == 0) {
print $pattern . "\n";
}
close(INPUT);

__END__
[/perl]

my fli4l router/server does

echo %d %t =\> `./number2name.pl %m`: `./number2name.pl %p` >> phonecalls.log

where %d is date, %t is time, %m is the called number on my side (aka MSN) and %p is the calling phone number.
It works very fine with the tick-a-stat gnome panel applet which follows the log file...