I am trying to create this Perl program:
#!/usr/bin/perl
use strict;
use warnings;
open(my $fh, "<", "test.txt")
or die "cannot open < file name: $!";
while (my $line = <$fh>) {
print $line;
}
close($fh);
I created this org file:
#+BABEL: :cache yes :tangle yes :noweb yes
#+NAME: top_block
#+begin_src perl :tangle test.pl
#!/usr/bin/perl
use strict;
use warnings;
open(my $fh, "<", "test.txt")
or die "cannot open < file name: $!";
<<output all the lines from file>>
close($fh);
#+end_src
#+NAME: output all the lines from file
#+begin_src perl :tangle test.pl
while (my $line = <$fh>) {
print $line;
}
#+end_src
But it created this:
empty line here
#!/usr/bin/perl
use strict;
use warnings;
open(my $fh, "<", "test.txt")
or die "cannot open < file name: $!";
<<output all the lines from file>>
close($fh);
while (my $line = <$fh>) {
print $line;
}
Problems:
There is an empty line at the top of the file.
Noweb block wasn't expanded, but put to the bottom of the file.
I don't understand, how to write the output file name once at the top? Currently, I have to rewrite it for every block: :tangle test.pl.
Here is the solution:
#+BABEL: :cache yes :tangle yes :noweb yes
#+NAME: top_block
#+begin_src perl :tangle "test.pl" :noweb tangle :shebang #!/usr/bin/perl
use strict;
use warnings;
open(my $fh, "<", "test.txt")
or die "cannot open < file name: $!";
<<output-all>>
close($fh);
#+end_src
#+NAME: output-all
#+begin_src perl
while (my $line = <$fh>) {
print $line;
}
#+end_src
To put #!/usr/bin/perl to the top line use :shebang #!/usr/bin/perl
Noweb blocks names shouldn't contain spaces. Replace them with "-".
Write the file name for the root noweb block.
Related
I have a file which contains a list of email addresses which are separated by a semi-colon which is configured much like this (but much larger) :
$ cat email_casper.txt
casper1#foo.com; casper2#foo.com; casper3#foo.com; casper.casper4#foo.com;
#these throw outlook error :
#casper101#foo.com ; casper100#foo.com
#cat /tmp/emailist.txt | tr '\n' '; '
#cat /tmp/emallist.txt | perl -nle 'print /\<(.*)\>/' | sort
I want to break it up on the semicolon - so I suck the whole file into an array supposedly the contents are split on semicolon.
#!/usr/bin/perl
use strict;
use warnings;
my $filename = shift #ARGV ;
open(my $fh, '<', $filename) or die "Could not open file $filename $!";
my #values = split(';', $fh);
foreach my $val (#values) {
print "$val\n";
}
exit 0 ;
But the file awards me with a golb. I just don't know what is going one.
$ ./spliton_semi.pl email_casper.txt
GLOB(0x80070b90)
If I use Data::Dumper I get
#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper ;
my $filename = shift #ARGV ;
open(my $fh, '<', $filename) or die "Could not open file $filename $!";
my #values = split(';', $fh);
print Dumper \#values ;
This is what the Dumper returns :
$ ./spliton_semi.pl email_casper.txt
$VAR1 = [
'GLOB(0x80070b90)'
];
You do not "suck the whole file into an array". You don't even attempt to read from the file handle. Instead, you pass the file handle to split. Expecting a string, it stringifies the file handle into GLOB(0x80070b90).
You could read the file into an array of lines as follows:
my #lines = <$fh>;
for my $line ($lines) {
...
}
But it's far simpler to read one line at a time.
while ( my $line = <$fh> ) {
...
}
In fact, there is no reason not to use ARGV here, simplifying your program to the following:
#!/usr/bin/perl
use strict;
use warnings;
use feature qw( say );
while (<>) {
chomp;
say for split /\s*;\s*/, $_;
}
This line
my #values = split(';', $fh);
is not reading from the filehandle like you think it is. You're actually calling split on the filehandle object itself.
You want this:
my $line = <$fh>;
my #values = split(';', $line);
Starting point:
#!/usr/bin/perl
use strict;
use warnings;
open(my $fh, '<', 'dummy.txt')
or die "$!";
my #values;
while (<$fh>) {
chomp;
# original
# push(#values, split(';', $_));
# handle white space
push(#values, split(/\s*;\s*/, $_));
}
close($fh);
foreach my $val (#values) {
print "$val\n";
}
exit 0;
Output for your example:
$ perl dummy.pl
casper1#foo.com
casper2#foo.com
casper3#foo.com
casper.casper4#foo.com
I'm really new to Perl programming and I'm writing a program that opens a file and reads in each line of the file one by one. It then outputs the file with a line number at the beginning of each line.
As of right now I'm reading in the lines, but I don't know how to distinguish individual lines and output something at the beginning.
#!/usr/bin/perl
use strict
use warnings
my $file = 'FILENAME.txt';
open(my $txt_file, '<', $file) or die "Could not open file."
while (my $lines = <$txt_file>) {
...
}
The $. variable holds the current line number for the last filehandle accessed:
#!/usr/bin/perl
use strict;
use warnings;
use autodie;
my $file = 'FILENAME.txt';
open my $fh, '<', $file;
while ( my $line = <$fh> ) {
print "$. $line";
}
My code did not work for my any modifications. other than append nothing works for in open close functions.
#!/usr/local/bin/perl
my $file = 'test';
open(INFO, $file);
print INFO "Add this line please\n";
print INFO "First line\n";
close(INFO);
You need to tell perl what type of filehandle you want
open(INFO, ">", "$file")|| die "Cannot open $file";
This will create and write to a file.
Look up
http://perldoc.perl.org/functions/open.html
By default open(INFO, $file) will take the file handle in read mode('<') . So until unless you specify the write mode('>') you cannot print the values into the file . When you write the code you should use : use strict; and use warnings; which will be helpful.
Code:
use strict;
use warnings;
my $InputFile = $ARGV[0];
open(FH,'<',"$InputFile")or die "Couldn't open the file $InputFile: $!";
my #file_content = <FH>;
close(FH);
open(FH,'>',"$InputFile") or die "Cannot open $InputFile: $!";
#String to be added at the begining of the file
my $file = "test";
print FH $file . "\n";
print FH #file_content;
close(FH);
I do a perl scrip that it creates a hash directly from the contents of the first file, and then reads each line of the second, checks the hash to see if it should be printed.
Here is the perl script :
use strict;
use warnings;
use autodie;
my %permitted = do {
open my $fh, '<', 'f1.txt';
map { /(.+?)\s+\(/, 1 } <$fh>;
};
open my $fh, '<', 'f2.txt';
while (<$fh>) {
my ($phrase) = /(.+?)\s+->/;
print if $permitted{$phrase};
}
I am looking for how i print the result in a file text because this script actually print the result on the screen.
Thank you in advance.
Cordially
$ perl thescript.pl > result.txt
Will run your script and put the printed output in result.txt
Or, from within the script itself:
use strict;
use warnings;
use autodie;
my %permitted = do {
open my $fh, '<', 'f1.txt';
map { /(.+?)\s+\(/, 1 } <$fh>;
};
# Open result.txt for writing:
open my $out_fh, '>', 'result.txt' or die "open: $!";
open my $fh, '<', 'f2.txt';
while (<$fh>) {
my ($phrase) = /(.+?)\s+->/;
# print output to result.txt
print $out_fh $_ if $permitted{$phrase};
}
Open a new filehandle in write mode, then print to it. See perldoc -f print or http://perldoc.perl.org/functions/print.html for more info
...
open my $fh, '<', 'f2.txt';
open my $out_fh, '>', 'output.txt';
while (<$fh>) {
my ($phrase) = /(.+?)\s+->/;
print $out_fh $_
if $permitted{$phrase};
}
mapping the file contents first produces a list of all of the file's lines. This isn't necessarily a bad thing, unless the file's substantially large. grebneke showed how to direct output to a file, using > result.txt. Given this, and the (possible) map issue, consider just passing both files to the script from the command line, and process them using whiles:
use strict;
use warnings;
my %permitted;
while (<>) {
$permitted{$1} = 1 if /(.+?)\s+\(/;
last if eof;
}
while (<>) {
print if /(.+?)\s+->/ and $permitted{$1};
}
Usage: perl script.pl f1.txt f2.txt > result.txt
Hope this helps!
I have a file named test.txt that is like this:
Test
Foo
Bar
But I want to put each line in a array and print the lines like this:
line1 line2 line3
But how can I do this?
#!/usr/bin/env perl
use strict;
use warnings;
my #array;
open(my $fh, "<", "test.txt")
or die "Failed to open file: $!\n";
while(<$fh>) {
chomp;
push #array, $_;
}
close $fh;
print join " ", #array;
Here is my single liner:
perl -e 'chomp(#a = <>); print join(" ", #a)' test.txt
Explanation:
read file by lines into #a array
chomp(..) - remove EOL symbols for each line
concatenate #a using space as separator
print result
pass file name as parameter
One more answer for you to choose from:
#!/usr/bin/env perl
open(FILE, "<", "test.txt") or die("Can't open file");
#lines = <FILE>;
close(FILE);
chomp(#lines);
print join(" ", #lines);
If you find yourself slurping files frequently, you could use the File::Slurp module from CPAN:
use strict;
use warnings;
use File::Slurp;
my #lines = read_file('test.txt');
chomp #lines;
print "#lines\n";
The most basic example looks like this:
#!/usr/bin/env perl
use strict;
use warnings;
open(F, "<", "test.txt") or die("Cannot open test.txt: $!\n"); # (1)
my #lines = ();
while(<F>) { chomp; push(#lines, $_); } # (2)
close(F);
print "#lines"; # (3) stringify
(1) is the place where the file is opened.
(2) File handles work nicely within list enviroments (scalar/list environments are defined by the left value), so if you assign an array to a file handle, all the lines are slurped into the array. The lines are delimited (ended) by the value of $/, the input record separator. If you use English;, you can use $IRS or $INPUT_RECORD_SEPARATOR. This value defaults to the newline character \n;
While this seemed to be a nice idea, I've just forgot the fact that if you print all the lines, the ending \n will be printed too. Baaad me.
Originally the code was:
my #lines = <F>;
instead of the while loop. This is still a viable alternative, but you should swap (3) with chomping and then printing/stringifying all the elements:
for (#lines) { chomp; }
print "#lines";
(3) Stringifying means converting an array to a string and inserting the value $" between the array elements. This defaults to a space.
See: the perlvar page.
So the actual 2nd try is:
#!/usr/bin/env perl
use strict;
use warnings;
open(F, "<", "test.txt") or die("Cannot open test.txt: $!\n"); # (1)
my #lines = <F>; # (2)
close(F);
chomp(#lines);
print "#lines"; # (3) stringify
This is the simplest version I could come up with:
perl -l040 -pe';' < test.txt
Which is roughly equivalent to:
perl -pe'
chomp; $\ = $/; # -l
$\ = 040; # -040
'
and:
perl -e'
LINE:
while (<>) {
chomp; $\ = $/; # -l
$\ = " "; # -040
} continue {
print or die "-p destination: $!\n";
}
'
This is the code that do this (assume the below code inside script.pl) :
use strict;
use warnings
my #array = <> ;
chomp #array;
print "#array";
It is run by:
scirpt.pl [your file]