Add headings to the a text file in perl - perl

I have a text file with the following lines as example
This is line
This is line with test
This is ine with 2test
This is line 2
This is line 3
This is line with 3test
This is line 4
This is line with 4test
Now I want a code to change the text file as follows:
Lines with test
This is line with test
This is ine with 2test
This is line with 3test
This is line with 4test
Lines without test
This is line
This is line 2
This is line 3
This is line 4
I am using the following code. I am assuming my code would print the title with every line but I am not able to execute the code due to some errors.
Can you please help me?
#!/usr/bin/perl
use strict;
use warnings;
open(FH, '<filetest.txt');
my #queues = <FH>;
close(FH);
open(OFH,'>testfile.txt');
my $name;
foreach $name(#queues)
{
if($name =~ 'test')
{
print OFH "Lines with test\n";
print OFH $1;
}
else{
print OFH "Lines without test\n";
print OFH $1;
}
close(OFH);
}
Note: I corrected the error to remove the syntax errors but still there is nothing being written to the file testfile.txt

Have a try with:
#!/usr/bin/perl
use strict;
use warnings;
my $infile = 'filetest.txt';
my $outfile = 'testfile.txt';
# use 3-arg open and if open succeeded
open my $fh_in, '<', $infile or die "Unable to open file '$infile' for reading: $!";
my #with_test;
my #without_test;
while (<$fh_in>) {
if (/test/) {
push #with_test, $_;
} else {
push #without_test, $_;
}
}
close $fh_in;
open my $fh_out, '>', $outfile or die "Unable to open file '$outile' for writting: $!";
print $fh_out "Lines with test\n";
print $fh_out #with_test;
print $fh_out "Lines without test\n";
print $fh_out #without_test;
close $fh_out;

I haven't tested this. The idea is to write the "with test" lines to the file immediately
The "without test" lines are stored (in an array called "without") until the end of the program and then written
#!/usr/bin/perl
use strict;
use warnings;
open(FH, '<filetest.txt');
my #queues = <FH>;
close(FH);
open(OFH,'>testfile.txt');
my $name;
my #without=();
foreach $name(#queues)
{
if($name =~ 'test')
{
print OFH $name;
}
else{
push #without, $name;
}
print OFH "\n\nlines without\n";
print OFH #without;
}

also you should add a local $/ before reading the file handle.
check this out:
how to read the whole file.
the match format should be like this: if($somestr =~ /#/).
and you shouldn't close the filehandle in the loop.
#!/usr/bin/perl
use strict;
use warnings;
local $/;
open(FH, 'file#.txt');
my $s;
$s = <FH>;
close(FH);
open(FH, '>file#.txt');
my #queues = split(/\n/, $s);
my #arr;
my #arr2;
for($s=0; $s<$#queues+1; $s++)
{
if($queues[$s] =~ /#/)
{
push(#arr, $queues[$s]."\n");
}
else
{
push(#arr2, $queues[$s]."\n");
}
}
print FH "lines with #\n";
print FH #arr;
print FH "lines without #\n";
print FH #arr2;

Related

Perl Search for string and print out line

I want to write a perl script that ask the user for a string and then finds the lines that contains that string and prints them.
This is what i have so far
#!/usr/bin/perl
use strict;
use warnings;
sub main
{
print "First name or Last Name or any portion: ";
my $name = <STDIN>;
my $file = '/home/jake/Downloads/phones';
open(FH, $file) or die("File $file not found");
while(my $String = <FH>)
{
if($String =~ $name)
{
print "$String \n";
}
}
close(FH);
}
main();
Whenever I try this the terminal doesnt print anything. Is there anything that I could do to fix that?
Try this out:
#!/usr/bin/perl
use strict;
use warnings;
sub main
{
print "First name or Last Name or any portion: ";
my $name = <STDIN>;
chomp $name;
my $file = '/home/jake/Downloads/phones';
open my $fh, '<', $file or die "$file: $!\n";
while(my $string = <$fh>)
{
if($string =~ /$name/)
{
print "$string\n";
}
}
close($fh);
}
main();
You need to omit the new line character using chomp.
Use a modern way to read a file, using a lexical filehandle.

Printing value from split result Perl

Here I have a abc.txt file:
aaa,1000,kevin
bbb,2000,john
ccc,3000,jane
ddd,4000,kevin
Then I want to print out:
kevin
john
jane
my Perl script is:
open (INFILE, $ARGV[1]) or die "An input file is required as argument\n";
#store=();
while(<INFILE>)
{
chomp();
#data=split(/,/);
#
#
#
if (%store ne "0")
{
print "Printing users:\n";
foreach $key (keys %store)
{print $key."\n";}
}
print "Printing users:\n";
foreach $key (keys %store)
{print $key."\n";}
}
My idea is to store the value into hash and create key to each value. How can I do in the ### line?
You have declared #store and then using %store. I didn't understand that why you doing that, but the below code will give you desire output. First read the input file, split the data and then remove the duplicates.
use strict;
use warnings;
my $infile = $ARGV[0];
open my $fh, "<", $infile or die "An input file is required as argument: $!";
my %store;
while(my $line = <$fh>)
{
chomp($line);
my #data = split /,/, $line;
my #removeduplicate = (grep { !$store{$_}++ } #data)[2];
foreach(#removeduplicate){
if( $_ ne ''){
print "$_\n";
}
}
}
close $fh;
Output:
kevin
john
jane
hmmm. it depends what do you want. maybe this example will help you:
#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper; #for debug if you want
my $infile='abc.txt'; #or ARGV[0] whatever it is
my $fh;
open $fh,'<',$infile or die "problem with $infile $# $!";
my $inputline;
my %Storage;
my #Values;
while (defined($inputline=<$fh>)) {
chomp $inputline;
#Values=split ',',$inputline;
if (#Values != 3) {
warn "$inputline has formatted badly";
next;
}
#warn if exists $Storage{$Values[1]}; #optional warning for detected duplicates
$Storage{$Values[1]}=#Values[0,2]; #create hash data
#duplicates will be removed automaticly
}
close $fh;
print Dumper \%Storage; #print how perl it stores
foreach my $Key (keys %Storage) { #example loop
print #{Storage->{$Key}},"\n"; #do anything
}
I hope this template will be enough for you.

Can't write to the file

Why can't I write output to the input file?
It prints it well, but isn't writing to the file.
my $i;
my $regex = $ARGV[0];
for (#ARGV[1 .. $#ARGV]){
open (my $fh, "<", "$_") or die ("Can't open the file[$_] ");
$i++;
foreach (<$fh>){
open (my $file, '>>', '/results.txt') or die ("Can't open the file "); #input file
for (<$file>){
print "Given regexp: $regex\nfile$i:\n line $.: $1\n" if $_ =~ /\b($regex)\b/;
}
}
}
It's unclear whether your problem has been solved.
My best guess is that you want your program to search for the regex passed as the first parameter in the files named in the following paramaters, appending the results to results.txt.
If that is right, then this is closer to what you need
use strict;
use warnings;
use autodie;
my $i;
my $regex = shift;
open my $out, '>>', 'results.txt';
for my $filename (#ARGV) {
open my $fh, '<', $filename;
++$i;
while (<$fh>) {
next unless /\b($regex)\b/;
print $out "Given regexp: $regex\n";
print $out "file$i:\n";
print $out "line $.: $1\n";
last;
}
}

How to read from a file and direct output to a file if a file name is given in the command line, and printing to console if no argument given

I made a file, "rootfile", that contains paths to certain files and the perl program mymd5.perl gets the md5sum for each file and prints it in a certain order. How do I redirect the output to a file if a name is given in the command line? For instance if I do
perl mymd5.perl md5file
then it will feed output to md5file. And if I just do
perl mydm5.perl
it will just print to the console.
This is my rootfile:
/usr/local/courses/cs3423/assign8/cmdscan.c
/usr/local/courses/cs3423/assign8/driver.c
/usr/local/courses/cs3423/assign1/xpostitplus-2.3-3.diff.gz
This is my program right now:
open($in, "rootfile") or die "Can't open rootfile: $!";
$flag = 0;
if ($ARGV[0]){
open($out,$ARGV[0]) or die "Can't open $ARGV[0]: $!";
$flag = 1;
}
if ($flag == 1) {
select $out;
}
while ($line = <$in>) {
$md5line = `md5sum $line`;
#md5arr = split(" ",$md5line);
if ($flag == 0) {
printf("%s\t%s\n",$md5arr[1],$md5arr[0]);
}
}
close($out);
If you don't give a FILEHANDLE to print or printf, the output will go to STDOUT (the console).
There are several way you can redirect the output of your print statements.
select $out; #everything you print after this line will go the file specified by the filehandle $out.
... #your print statements come here.
close $out; #close connection when done to avoid counfusing the rest of the program.
#or you can use the filehandle right after the print statement as in:
print $out "Hello World!\n";
You can print a filename influenced by the value in #ARGV as follows:
This will take the name of the file in $ARGV[0] and use it to name a new file, edit.$ARGV[0]
#!/usr/bin/perl
use warnings;
use strict;
my $file = $ARGV[0];
open my $input, '<', $file or die $!;
my $editedfile = "edit.$file";
open my $name_change, '>', $editedfile or die $!;
if ($input eq "md5file"){
while ($in){
# Do something...
print $name_change "$_\n";
}
}
Perhaps the following will be helpful:
use strict;
use warnings;
while (<>) {
my $md5line = `md5sum $_`;
my #md5arr = split( " ", $md5line );
printf( "%s\t%s\n", $md5arr[1], $md5arr[0] );
}
Usage: perl mydm5.pl rootfile [>md5file]
The last, optional parameter will direct output to the file md5file; if absent, the results are printed to the console.

I am looking to input a file in Perl and then export it changed

I am looking to change a txt file in Perl, by input the file, then exporting it with a blank line in between the existing ones. How do i do this? I have this so far:
#!/usr/bin/perl;
use strict;
use warnings;
print "Hi! This Program Will Input\n";
print "The File and Export A New\n";
print "File With A Blank Line In-Between\n";
print "Every Other Line\n";
sleep(2);
print "\n";
print "\n";
print "Working\n";
print "\n";
sleep(1);
print "\n";
print "Working\n";
sleep(1);
open(my $in, "<", "input.txt") or die "Can't Open Input.txt: $!";
open(my $out, ">", "output.txt") or die "Can't Open Output.txt: $!";
my #lines = <$in>;
while (<$in>) {
print $out
print $lines[$#lines];
print " ";
}
print "Completed Successfully!!\n";
print "\n";
print "Outputed to Output.txt\n";
close $in or die "$in: $!"
What am i missing? I am only just learning Perl so i do not know much at all.
The problem is the while loop. You can iterate over the filehandle with the while, or do a loop over the array where you saved the file content with for. Iterators can be processed once until they are exhausted, and you do it to extract all its content to the array, it's wrong to process it again in the while loop.
Besides that, to print to a filehandle you have to pass it as first argument to the print() function in the same call, and " " is not a newline, \n is a newline.
my #lines = <$in>;
#while (<$in>) {
for ( #lines ) {
print $out $_;
print $out "\n";
}
But you can forget all that code and learn the one-liners. This yields same result:
perl -ne 'print "$_\n"' input.txt >output.txt