Need to search and replace the string in multiple file of same extension using perl.
I am using this code, but it is not working as expected. Can anyone please help.
#!/usr/bin/perl
use strict;
use warnings;
use English;
use Tie::File;
my $string2 = 'li role="prep" class="active"'; #old string
my $string3 = 'li role="presentation"'; #new string
my $string6 = 'div role="tabpanel" class="tab-pane active" id="documentation"'; #old string
my $string7 = 'div role="tabpanel" class="tab-pane" id="documentation"'; #new string
my $quoted_substring = quotemeta($string2);
my $quoted_substring2 = quotemeta($string6);
my $dir = 'C:\Users\vkpal\Desktop\New_Report';
foreach my $fp (glob("$dir/*.html")) {
chomp($fp);
printf "%s\n", $fp;
open my $fh, "<", $fp or die "can't read open '$fp': $OS_ERROR";
while (<$fh>) {
#printf " %s", $_;
s/$quoted_substring/$string3/g;
s/$quoted_substring2/$string7/g;
}
close $fh or die "can't read close '$fp': $OS_ERROR";
}
I am using above code but it is not replacing the string. Can anyone please me here.
Related
Code which i have tried for single file:
#!/usr/bin/perl
use strict;
use warnings;
open my $HTML, '>', 'h.html' or die $!;
print $HTML <<'_END_HEADER_';
<html>
<head><title></title></head>
<body>
_END_HEADER_
open my $IN, '<', 'h.txt' or die $!;
while (my $line = <$IN>) {
# You probably want to do more work here.
print $HTML $line;
}
print $HTML '</body></html>';
close $HTML or die $!;
Query:
The above code converts .txt to .html file format.In this code i have tried for single file.I got struck with how can i do for multiple files from the folder using perl?
Input files:
h.txt
e.txt
l.txt
Expected output;(With html formt)
h.html
e.html
l.html
Try glob. It return the list of filename for mentioned directory.
#!/usr/bin/perl
use strict;
use warnings;
open my $HTML, '>', 'h.html' or die $!;
print $HTML <<'_END_HEADER_';
<html>
<head><title></title></head>
<body>
_END_HEADER_
while (my $file= glob("~/Desktop/*.txt"))
{
open my $IN, '<', $file or die $!;
while (my $line = <$IN>)
{
print $HTML $line;
}
}
print $HTML '</body></html>';
close $HTML or die $!;
Writing into new file
#!/usr/bin/perl
use strict;
use warnings;
my $HTML;
#open my $HTML, '>', 'h.html' or die $!;
while (my $file= glob("~/Desktop/*.txt"))
{
open my $IN, '<', $file or die $!;
my $new_file_name = $file;
$new_file_name=~s/.+\///;
open $HTML, '>', "$new_file_name.html" or die $!;
print $HTML "
<html>
<head><title></title></head>
<body>";
while (my $line = <$IN>)
{
print $HTML $line;
}
print $HTML '</body></html>';
close $HTML;
}
So I am trying to teach myself perl as a new language. I find the best way to learn a new language is to set myself a project. This project is a text game. I have just started this evening. I need to take input from the user and then write it to a file. As I am going to be doing this over and over again, I thought it would be best to put the code in subroutines, as you can see below.
The only problem is that I keep getting the following error:
Can't use an undefined value as a symbol reference at book1.pl line 12, <> line 2.
Any help would be greatly appreciated :)
#!/usr/bin/perl
use 5.010;
use strict;
use warnings;
my $filename = 'save.txt';
sub open_save{
open(my $fh, '>', $filename) or die "Could not open file '$filename' $!";
}
sub close_save{
close my $fh;
}
print "Welcome to the 40K universe\nWhat is your first name?";
my $first_name = <>;
print"What is your surname?";
my $surname = <>;
my $name = $first_name . $surname;
open_save();
print "$name";
close_save();
my creates and returns a new variable. You pass this new variable to close, which quite legitimately complains that it's not a file handle.
#!/usr/bin/perl
use 5.010;
use strict;
use warnings;
sub open_save {
my ($filename) = #_;
open(my $fh, '>', $filename)
or die "Can't open file '$filename': $!\n";
return $fh;
}
sub close_save {
my ($fh) = #_;
close $fh;
}
{
my $filename = 'save.txt';
...
my $fh = open_save($filename);
print $fh "$name\n";
close_save($fh);
}
I've got the following code:
#!/usr/bin/perl
use strict;
use warnings;
my $usage = "Usage: $0 <infile.txt> <outfile.txt>\n";
my $infile = shift or die $usage;
my $outfile = shift or die $usage;
open (my $data, "<", $infile) or die "There was a problem opening: $!";
my #primers = <$data>;
close $data;
chomp #primers;
use Algorithm::Combinatorics qw(combinations);
my $strings = \#primers;
my $iter = combinations($strings, 2);
open(my $fh, '>', $outfile);
while (my $c = $iter->next) {
print $fh join('',#$c) ."\n";
}
Which works just fine however I would prefer if the user did not have to specify the output directory and filename. Is there an easy way to get Perl to print the output to the same directory as infile but also giving the output file a specific name such as 'output.txt'?
Any pointers would be greatly appreciated!
Thanks.
SOLVED:
#!/usr/bin/perl
use strict;
use warnings;
my $usage = "Usage: $0 <infile.txt>\n";
my $infile = shift or die $usage;
use File::Basename;
my $DIR = dirname($infile);
my $outfile = $DIR . "/results.txt" or die $usage;
open (my $data, "<", $infile) or die "There was a problem opening: $!";
my #primers = <$data>;
close $data;
chomp #primers;
use Algorithm::Combinatorics qw(combinations);
my $strings = \#primers;
my $iter = combinations($strings, 2);
open(my $fh, '>', $outfile);
while (my $c = $iter->next) {
print $fh join('',#$c) ."\n";
}
print ("Finished. The results are located at $outfile\n\n");
If I understand you correctly, you are trying to write the output to the same directory as input file. If so, you can use File::Basename module to get the directory of the input file.
How about
my $outfile=$infile . ".combinations"
Or, better yet, use stdin and stdout.
(also, check that your outfile was opened succesfully)
I have this little perl script which opens a txt file, reads the number in it, then overwrites the file with the number incremented by 1. I can open and read from the file, I can write to the file but I"m having issues overwriting. In addition, I'm wondering if there is a way to do this without opening the file twice. Here's my code:
#!/usr/bin/perl
open (FILE, "<", "data.txt") or die "$! error trying to a\
ppend";
undef $/;
$number = <FILE>;
$number = int($number);
$myNumber = $number++;
print $myNumber+'\n';
close(FILE);
open(FILE, ">data.txt") or die "$! error";
print FILE $myNumber;
close(FILE);
Change the line
$myNumber = $number++;
to
$myNumber = $number+1;
That should solve the problem.
Below is how you could do by opening the file just once:
open(FILE, "+<data.txt") or die "$! error";
undef $/;
$number = <FILE>;
$number = int($number);
$myNumber = $number+1;
seek(FILE, 0, 0);
truncate(FILE, tell FILE);
print $myNumber+"\n";
print FILE $myNumber;
close(FILE);
It's good that you used the three-argument form of open the first time. You also needed to do that in your second open. Also, you should use lexical variables, i.e., those which begin with my, in your script--even for your file handles.
You can just increment the variable that holds the number, instead of passing it to a new variable. Also, it's a good idea to use chomp. This things being said, consider the following option:
#!/usr/bin/env perl
use strict;
use warnings;
undef $/;
open my $fhIN, "<", "data.txt" or die "Error trying to open for reading: $!";
chomp( my $number = <$fhIN> );
close $fhIN;
$number++;
open my $fhOUT, ">", "data.txt" or die "Error trying to open for writing: $!";
print $fhOUT $number;
close $fhOUT;
Another option is to use the Module File::Slurp, letting it handle all the I/O operations:
#!/usr/bin/env perl
use strict;
use warnings;
use File::Slurp qw/edit_file/;
edit_file { chomp; $_++ } 'data.txt';
Try this:
#!/usr/bin/perl
use strict;
use warnings;
my $file = "data.txt";
my $number = 0;
my $fh;
if( -e $file ) {
open $fh, "+<", $file or die "Opening '$file' failed, because $!\n";
$number = <$fh>;
seek( $fh, 0, 0 );
} else { # if no data.txt exists - yet
open $fh, ">", $file or die "Creating '$file' failed, because $!\n";
}
$number++;
print "$number\n";
print $fh $number;
close( $fh );
If you're using a bash shell, and you save the code to test.pl, you can test it with:
for i in {1..10}; do ./test.pl; done
Then 'cat data.txt', should show a 10.
I want to extract the desired information from a file and append it into another. the first file consists of some lines as the header without a specific pattern and just ends with the "END OF HEADER" string. I wrote the following code for find the matching line for end of the header:
$find = "END OF HEADER";
open FILEHANDLE, $filename_path;
while (<FILEHANDLE>) {
my $line = $_;
if ($line =~ /$find/) {
#??? what shall I do here???
}
}
, but I don't know how can I get the rest of the file and append it to the other file.
Thank you for any help
I guess if the content of the file isn't enormous you can just load the whole file in a scalar and just split it with the "END OF HEADER" then print the output of the right side of the split in the new file (appending)
open READHANDLE, 'readfile.txt' or die $!;
my $content = do { local $/; <READHANDLE> };
close READHANDLE;
my (undef,$restcontent) = split(/END OF HEADER/,$content);
open WRITEHANDLE, '>>writefile.txt' or die $!;
print WRITEHANDLE $restcontent;
close WRITEHANDLE;
This code will take the filenames from the command line, print all files up to END OF HEADER from the first file, followed by all lines from the second file. Note that the output is sent to STDOUT so you will have to redirect the output, like this:
perl program.pl headfile.txt mainfile.txt > newfile.txt
Update Now modified to print all of the first file after the line END OF HEADER followed by all of the second file
use strict;
use warnings;
my ($header_file, $main_file) = #ARGV;
open my $fh, '<', $header_file or die $!;
my $print;
while (<$fh>) {
print if $print;
$print ||= /END OF HEADER/;
}
open $fh, '<', $main_file or die $!;
print while <$fh>;
use strict;
use warnings;
use File::Slurp;
my #lines = read_file('readfile.txt');
while ( my $line = shift #lines) {
next unless ($line =~ m/END OF HEADER/);
last;
}
append_file('writefile.txt', #lines);
I believe this will do what you need:
use strict;
use warnings;
my $find = 'END OF HEADER';
my $fileContents;
{
local $/;
open my $fh_read, '<', 'theFile.txt' or die $!;
$fileContents = <$fh_read>;
}
my ($restOfFile) = $fileContents =~ /$find(.+)/s;
open my $fh_write, '>>', 'theFileToAppend.txt' or die $!;
print $fh_write $restOfFile;
close $fh_write;
my $status = 0;
my $find = "END OF HEADER";
open my $fh_write, '>', $file_write
or die "Can't open file $file_write $!";
open my $fh_read, '<', $file_read
or die "Can't open file $file_read $!";
LINE:
while (my $line = <$fh_read>) {
if ($line =~ /$find/) {
$status = 1;
next LINE;
}
print $fh_write $line if $status;
}
close $fh_read;
close $fh_write;