I'd like to write sth like:
die "Error in file $0 line number $line_number_of_this_cmd_in_file \n";
In my perl script file.
Any help?
Thx a lot!
(perl 5)
If you do not put \n at the end of the string you pass to die, then perl will automatically add the line number.
Otherwise, the token __LINE__ will give you the current line number in your script (and __FILE__ gives the current file name).
Unless you meant the current line number of the file you just read from - that is available in $.
That is quite easy: Drop the \n at the end of the line and die will append whatever message you wrote with the name of the script and the line number.
For example:
die "Encountered error 15 ";
will result in it printing:
"Encountered error 15 at script.pl line 42\n"
or whatever is applicable.
Related
I am looking for a solution to below case.
I need to read task.txt file from my Perl script disconnect.pl,
and I have to save the content of file to variable which I can use in multiple places in my Perl script.
Task.txt file contains words in single quotes separated by comma but in a single line like below
'qbc','456','sdf','fgh'
#########################
my $filename = 'testing_folder/text_document.txt';
open(FH, '<', $filename) or die $!;
while(<FH>){
$content=$_
}
print "$content"
my $ql = "select in ($content)";
print "$ql"
###############################
It's giving error at line my $ql
I put your code into a file called "line" and tried to run it. Here's what happened:
$ perl line
syntax error at line line 8, near "my "
Execution of line aborted due to compilation errors.
As you say, line 8 is this line:
my $ql = "select in ($content)";
But here's a little secret about compiler error messages - they aren't as clever as we'd like them to be. And one common problem that you'll see is that they often report an error on the wrong line. So it's always worth checking the line or two before where the error is reported.
In this case, the problem is on the previous line:
print "$content"
Can you see it now? Take a close look at the end of that line. Do you see anything missing?
Perl statements are separated by semicolons. Newlines (usually) mean nothing to the Perl compiler. Perl is happy for you to spread a statement over two or more lines. So when it comes across a line without a semicolon at the end, it just assumes that the next line is a continuation of the same statement.
Which means that when you write:
print "$content"
my $ql = "select in ($content)";
Perl sees it as one statement:
print "$content" my $ql = "select in ($content)";
And that's a statement that doesn't make sense. So the compiler gives an error.
That also explains why the error reporting is a line out. Perl reports the error at the end of the problematic statement.
Oh. And in case I wasn't clear - you need a semicolon on the end of that line.
If I run a perl program and call another perl program using backquotes, print statements from the called program don't appear at the terminal.
If I call the program using 'system', the print statements are displayed.
EG:
This is ProgA.pl
print "In ProgA.pl, about to call ProgB.pl";
my $dum=`ProgB.pl`; # print output doesn't appear
### $dum=system("ProgB.pl"); # this prints OK
print"\nBack in ProgA.pl";
print "\ndum = $dum"; # ProgB's output doesn't show here either
(No warnings or errors, perl.exe found through file association)
This is ProgB.pl:
print "\nPrinting from ProgB.pl";
What is the reason for the difference?
Why isn't the backquoted call output returned in $dum (I tried both STDOUT and STDERR)? If I call dir in backquotes, I get its output in $dum.
You have a path issue.
It works as expected ($dum is assigned the value "Printing from ProgB.pl") if I change the backticks from ProgB.pl to ./ProgB.pl. Without the explicit ./ path, it searches the system path and generates an error, as you can see if you change that line to
my $dum=`ProgB.pl` or die $!;
Which generates the output
In ProgA.pl, about to call ProgB.plNo such file or directory at ./ProgA.pl line 4.
Thus illustrating once again that you should always check the return values of your system calls for error conditions.
It appears that by failing to put a newline character at the end of the print command in ProgB, I failed to flush the buffer before returning to ProgA. Thanks to Chris Turner.
Frequently [not always] when i run procedure define a file handler i get strange error on internal function which i dont understand how to debug.
In My PERL code i have the following line [111]:
open V_FILE_SEC, ">>$file/V_$file$dir.csvT" or die $!;
And when i am operating the script [>myscript.pl DPX_*] i get:
"No such file or directory at myscript.pl line 111, line 18004."
What is the meaning of line 18004? How to start debug?
Thanks.
From perldoc -f die:
If the last element of LIST does not end in a newline, the current script line number and input line number (if any) are also printed, and a newline is supplied. [Emphasis added]
The "input line number" is the value in $., roughly the number of lines of input you have read from the most recent filehandle you accessed.
In your case, you could use to look at your program input and see if there is anything unusual around line 18004 that your program wasn't expecting.
OK I have a file which is a list of over 5000 names, one line each;
the file is a txt file generated with microsoft excel.
The following code gave me an output of 1.
open FILEHANDLE, "< listname_FC2-3ss>0.txt";
chomp (my #genelist = <FILEHANDLE>);
close FILEHANDLE;
print "the number of item in the list is ";
print scalar #genelist;
I'm using a '10 macbook air, perl 5.12.I tried to output the list and its the last line of the file.
But I tried the code on a tiny version of 10 names which I extracted by hand myself and it worked perfectly fine, so i reckon it's got something to do with the delimiter?
Please help.
Ian
Try with
local $/ = "\r";
before file reading. It changes the input record separator to the "\r" character.
My assignment is a little more in depth than the title but in the title is my main question. Here is the assignment:
Write a perl script that will grep for all occurrences of the regular expression in all regular files in the file/directory list as well as all regular files under the directories in the file/directory list. If a file is not a TEXT file then the file should first be operated on by the unix command strings (no switches) and the resulting lines searched. If the -l switch is given only the file name of the files containing the regular expression should be printed, one per line. A file name should occur a maximum of one time in this case. If the -l switch is not given then all matching lines should be printed, each proceeded on the same line by the file name and a colon. An example invocation from the command line:
plgrep 'ba+d' file1 dir1 dir2 file2 file3 dir3
Here is my code:
#!/usr/bin/perl -w
use Getopt::Long;
my $fname = 0;
GetOptions ('l' => \$fname);
$pat = shift #ARGV;
while (<>) {
if (/$pat/) {
$fname ? print "$ARGV\n" : print "$ARGV:$_";
}
}
So far that code does everything it's supposed to except for reading non-text files and printing out duplicates of file names when using the -l switch. Here is an example of my output after entering the following on the command line: plgrep 'ba+d' file1 file2
file1:My dog is bad.
file1:My dog is very baaaaaad.
file2:I am bad at the guitar.
file2:Even though I am bad at the guitar, it is still fun to play!
Which is PERFECT!
But when I use the -l switch to print out only the file names this is what I get after entering the following on the command line: plgrep -l 'ba+d' file1 file2
file1
file1
file2
file2
How do I get rid of those duplicates so it only prints:
file1
file2
I have tried:
$pat = shift #ARGV;
while (<>) {
if (/$pat/) {
$seen{$ARGV}++;
$fname ? print "$ARGV\n" unless ($seen{$ARGV} > 1); : print "$ARGV:$_";
}
}
But when I try to run it without the -l switch I only get:
file1:My dog is bad.
file2:I am bad at the guitar.
I also tried:
$fname ? print "$ARGV\n" unless ($ARGV > 1) : print "$ARGV:$_";
But I keep getting syntax error at plgrep line 17, near ""$ARGV\n" unless"
If someone could help me out with my duplicates issue as well as the italicized part of the assignment I would truly appreciate it. I don't even know where to start on that italicized part.
If you're printing only file names, you can exit the loop (using the last command) after the first match, since you already know the file matches. By not scanning the rest of the file, this will also prevent the name from being printed repeatedly.
Edited to add: In order to do it this way, you'll also need to switch from using <> to read the files to instead getting the names from #ARGV and opening them normally.
If you want to continue using <>, you'll instead need to watch $ARGV to see when it changes (indicating that you've started reading a new file) and keep a flag to indicate whether the current file has found any matches yet or not. However, this approach would require you to read every file in its entirety, which will be less efficient than only reading enough of each file to know whether it contains at least one match or not (i.e., skipping to the next file after the first match), so I would recommend switching to open instead.
The first syntax problem is simply an extra semicolon.
The second is that you may only use if/unless as a statement modifier at the end of a statement - you can't embed it in the middle of a conditional that way.
$fname ? print "$ARGV\n" unless ($seen{$ARGV} > 1); : print "$ARGV:$_";
Becomes:
next if $seen{$ARGV} > 1;
print $fname ? "$ARGV\n" : "$ARGV:$_";