Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 2 years ago.
Improve this question
Wondering if it's possible to write a short script that prints the code itself out in the end with the lines counted. Even something simple like a few lines of
#!/usr/bin/perl
use strict;
print "Hello there";
print "This got me scratching my head";
And the output would be this code itself with the lines counted.
Thanks a lot in advance.
Something like this?
use warnings;
use strict;
print "Hello there";
print "This got me scratching my head";
open (my $f, '<', $0);
while (<$f>){print};
print "read $. lines\n";
The variable $0 or $PROGRAM_NAME holds the name of your program.
Or (with linecount on each line)
use warnings;
use strict;
print "Hello there";
print "This got me scratching my head\n";
open (my $f, '<', $0);
while (<$f>){printf "%03d %s",$., $_};
print "read $. lines\n";
The variable $. or $INPUT_LINE_NUMBER contains the current line number for the last filehandle accessed.
See perlvar
Also see mobs answer for a way to read the file using DATA
The name of the script being executed is in the variable $0, so the straightforward way to accomplish this is
...
open(my $ZERO,"<",$0);
my #lines = <$ZERO>;
close $ZERO;
print #lines, "count = ", 0+#lines, "\n";
...
When $0 is unavailable because you have changed directories or overwritten it, another option is to use the special DATA handle which is opened on a file that contains the special __END__ or __DATA__ tokens.
...
seek DATA, 0, 0; # seek to begin of file, not begin of __DATA__ section
my #lines = <DATA>;
print #lines, "count = ",0+#lines,"\n";
...
__DATA__
...
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I am trying to get this script to work in regards to two find strings. I am having trouble getting the file to export the format I am looking for.
use strict;
my $find = '^(H0|HT)';
open (NEW, ">", "output.txt" ) or die "could not open:$!";
open (FILE, "<", "input.txt") or die "could not open:$!";
while (<FILE>) {
chomp;
if (/^\h{39}\XX187/){
print NEW join(",","$_\n");
}
if (/$find/){
print NEW join(",","$_")
}
}
close (FILE);
close (NEW);
Input File:
Txn Bch
Account Patient Name Date
--------------------------------------------------------------------------------------------
HT12345678 TEST,TESTNAME 01/01/16
XX187 CLAIM PROCESSED 01/01/16
Output File (Expectation):
HT12345678 TEST, TESTNAME 01/01/16 XX187 CLAIM PROCESSED 01/01/16
Your question is very imprecise, and I'm having trouble understanding exactly what it is that you need. However, this short program may help
use strict;
use warnings 'all';
while ( <DATA> ) {
print if /^(?:H[0T]|\s+XX187\b)/;
}
__DATA__
Account Patient Name Date
--------------------------------------------------------------------------------------------
HT12345678 TEST,TESTNAME 01/01/16
XX187 CLAIM PROCESSED 01/01/16
output
HT12345678 TEST,TESTNAME 01/01/16
XX187 CLAIM PROCESSED 01/01/16
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 7 years ago.
Improve this question
I have a Perl script, which has to read a file line by line.
Line in the file:
0060|9592014|A001-9592014-0060|82769|NOVARTIS PHARMA SERVICES AG BASEL|51671|NOVARTIS AG|A+|SWITZERLAND|Guarantees Issued|12/31/2016|12/31/2016|0|0|0|0|0|0|0|0|0|29014.0967835279993469339764885601502052|0||||0|1|550.3648|32541||.32|SUIG|OLEG|AAA||||||END|
I need to get only 32 fields, the first 32.
open (PRISM, "$infile") or die "Can't open $infile\n";
while (my $file_line = <PRISM>)
{
last if ($file_line=~/^PRISMEXP/);
next if ($file_line=~/^(\s)*$/); # Skip blank lines
print "LINE: $file_line\n"; # This line doesn't print anything
my #field = (split /\|/, $file_line[0-32]);
print "$field[0]\n"; #This line doesn't print anything
}
And as you can see, this part of code doesn't read the file and doesn't print anything. Why? Where is my mistake?
Where you have WHILE you should have while.
Also, your blank line check should have =~, not =.
Your split uses $file_line[0-32] is the same thing as $file_line[-32], which is the 32nd element from the end of #file_line, but you haven't set that array anywhere; I'm guessing that should be substr($file_line,0,32).
Or, if you only want the first 32 fields, it should be:
my #field;
#field[0..31] = split /\|/, $file_line;
Always use use strict; use warnings;. It would have caught the last error, and likely the second error too.
Here are some notes on your program that should help you improve your success rate
Always use strict and use warnings at the top of every Perl program, if you haven't done that already
Use lexical file handles, like my $prism_fh instead of global bareword file handles like PRISM
Don't put scalar variables inside double quotes. At best it will make no difference, and at worst you will get a completely different string
Always put the $! variable in your die string when checking the status of open calls. It will tell you why the open failed. Also, perl will add the source file name and line number to the output of die unless you put a newline on the end of your string, so don't do that if you want to know where in your code the error occurred
It is often better to use the default variable $_ when reading from a file. Many operators use it as their default parameter, making for more concise and tidy code
Don't forget unless. You can more cleanly check whether a line contains non-blanks by using next unless $file_line =~ /\S/
If you don't chomp the input lines then there is no need to put a newline on the end when you print the output
You need to split lines before you can select fields from the input $file_line[0-32] isn't valid Perl
Here's your Perl code refactored so that it prints the first 32 pipe-separated fields. I hope it is obvious that it needs a preamble that does use strict and use warnings and defines $infile.
open my $prism_fh, '<', $infile or die qq{Can't open "$infile": $!\n};
while (<$prism_fh>) {
next unless /\S/;
last if /^PRISMEXP/;
chomp;
my #fields = (split /\|/);
print join('|', #fields[0 .. 31]), "\n";
}
output
0060|9592014|A001-9592014-0060|82769|NOVARTIS PHARMA SERVICES AG BASEL|51671|NOVARTIS AG|A+|SWITZERLAND|Guarantees Issued|12/31/2016|12/31/2016|0|0|0|0|0|0|0|0|0|29014.0967835279993469339764885601502052|0||||0|1|550.3648|32541||.32
Update
Instead of splitting and recombining, you could use a regular expression to grab the first 32 pipe-separated fields, like this
while (<$prism_fh) {
next unless /\S/;
last if /^PRISMEXP/;
chomp;
print $1, "\n" if /^((?:[^|]*\|){31}[^|]*)/;
}
The output is identical to that of the program above.
Because of the line:
last if ($file_line=~/^PRISMEXP/);
If the first line of $infile begins with PRISMEXP you will never print anything.
You have also to change the line:
my #field = (split /\|/, $file_line[0-32]);
to:
my #field = (split /\|/, $file_line)[0..32];
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 9 years ago.
Improve this question
Can anyone tell me why I'm getting this:
usage: gen-non-random.pl <count> <outputfile>
From the code below:
#!/usr/bin/perl -w
#
# Script to generate non random values, to demonstrate a bad randomness graph
# for my "Howto Analyse SessionIDs".
#
# written by:
$version = "0.0.4";
$filename = "gen-non-random.pl";
$usage = "usage: $filename <count> <outputfile>\n";
$count = $ARGV[0] or die ("$usage\n");
$output = $ARGV[1] or die ("$usage\n");
print ("-- $filename Version: $version\n");
use Time::HiRes qw( usleep ualarm gettimeofday tv_interval );
use Math::Random;
use Digest::MD5 qw(md5_hex);
open (OUT, ">$output") or die ("Can't open $output\n");
for ($i=0; $i<$count;$i++)
{
# generate a random number
$random = random_uniform();
# cut out char 3-9 of $random and put it in $randsub
$randsub = substr($random, 2, 6);
# get seconds and microseconds since epoch
($seconds, $microseconds) = gettimeofday;
# get the last two chars of the seconds and put them into $s
$s = substr($seconds, 8, 2);
# sleep for a while
usleep $randsub;
# put together the last two digits of seconds and the microseconds
$time = $s . $microseconds;
$md5_time=md5_hex($time);
# print out the stuff we put together above
print OUT ("$md5_time\n");
}
close (OUT) or die ("Can't close $output\n");
print ("$count values written to $output\n");
exit;
I am new to programming so i need really simple answer please! I do not own this code I am using for my research paper at University. Also, could someone please explain to me what Usage actually is i can't seem to find a good explanation for it?
Thanks.
You're getting that error because you're not using the program correctly:
usage: gen-non-random.pl <count> <outputfile>
This basically means you have to provide a count and output file as arguments, such as:
perl gen-non-random.pl 42 outfile.txt
This will generate forty-two numbers and output them to the outfile.txt file.
It's the two lines near the start, checking ARGV[0/1] and die-ing if you don't provide them, that are outputting this message and exiting the program.
Hmmm. I can't run the above code because Time::HiRes::ualarm() is not implemented on Windows. That said, it appears to be generating a MD5 has string of the current time (in integer form) after sleeping for a random number of seconds, then dumping the result into a text file. You are getting the usage message mentioned above because the program expects input. Try running it from the command line like so:
perl gen-non-random.pl 10 MyResults.txt
I suspect that will dump 10 HD5 hash results into a file called "MyResults.txt".
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I want to remove every lines in a text file that contain the word "script" and then write whatever left into another file. But keep the originl file.
like this:
open the file
delete any line with the word "script"
then output whatever left after delete to another file.
perl -ne '/script/ or print' file > newfile
grep -v script original.file > new.file
Or if you really need perl:
#!/usr/bin/perl
use strict;
use warnings;
open(my $in, '<', 'input.txt')
or die "Cannot open input.txt: $!";
open(my $out, '>', 'output.txt')
or die "Cannot open output.txt: $!";
while (<$in>) {
print $out $_ unless /script/;
}
close($in);
close($out);
Finally, if you are only looking to match "script" if it is a word (and not part of a bigger string like "prescription" or "scripting") then change:
/script/
To:
/\bscript\b/
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I'm writing a Perl script. If the text in a specified column (here column 13) matches a certain text namely 'one' or 'two', then the whole line (so all columns) should be copied to another file. My input is a tab-delimited .txt file.
This is what I have so far:
my $table1 = $ARGV[0];
open(my $variants,$table1) || die "$! $table1";
open(my $out,'>',"filtered.txt") || die "Can't write new file: $!";
while(<$variants>){
chomp;
my #line=split(/\t/); #split on tabs
if (($line[12] =~ m/one/) || ($line[12] =~ m/two/)){
print $out "$_";
}
}
Since I'm getting a 'use of uninitialized value' error, I wanted to know what needs to be changed in this code.
What is the problem?
perl -F'\t' -ane'print if $F[11]=~/one|two/' input > output
This is a great example of a program that should be written using the Unix filter model.
#!/usr/bin/perl
use strict;
use warnings;
while (<>) {
my #line = split /\t/;
# Do you mean 12? That's the 13th field
print if $line[12] =~ /one/ || $line[12] =~ /two/;
}
Simpler to write and easier to understand. Oh, and far more flexible (no hardcoded filenames).
Call it like this:
$ ./my_filter < input_file.txt > output_file.txt