1

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

user3164754
  • 205
  • 2
  • 9
  • “due to some errors” – syntax errors, to be exact. Tip: the source for the error is likely to be a bit before the location where the error was reported. Note also that `#` begins a line comment, and that regexes must use some kind of regex quote like `/foo/`. But even after that, your code has various bugs. (1) Reading and writing to the same file at once isn't going to work. (2) You're using antiquated syntax for `open` and don't perform any error checking. (3) `$1` isn't going to be populated. Use `$_`. (4) You output the heading for *each* line. Instead, put the lines into arrays first. (…) – amon Jan 16 '14 at 09:25

3 Answers3

2

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;
Toto
  • 89,455
  • 62
  • 89
  • 125
  • Thanks M42. This is working. I actually changed your script a little bit so the output is written to the infile itself. i don't need the copy of the infile. Do you see any issue in doing this? – user3164754 Jan 16 '14 at 11:22
  • @user3164754: You're welcome. You can use the same file for input and output because the input file is closed before it's opened for output. But I'd do a backup before processing... – Toto Jan 16 '14 at 11:50
1

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;

}
Vorsprung
  • 32,923
  • 5
  • 39
  • 63
0

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;
Community
  • 1
  • 1
V1R4N64R
  • 23
  • 1
  • 8
  • Why would you localize `$/` and then re-implement it's functionality with `split`? Leaving `$/` alone and reading the whole file into an array is far more efficient. Also why would you use a (potentially buggy) C-style for loop instead of a foreach loop? You also shouldn't re-use `$s` like that. The only part of this answer that is better than the question is that you push the elements into two arrays. – Brad Gilbert Jan 17 '14 at 06:26