?
Solved

add/delete line in file with perl

Posted on 2003-03-24
9
Medium Priority
?
1,099 Views
Last Modified: 2008-01-09
Let say I have a file named abc.txt. And I would like to delete a line with the sentence "Pls delete this line" in the file and add a new line with "deleted successfully" at the end of the file. How to I do it in perl? Pls give advice to me.
0
Comment
Question by:abc88
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 2
  • 2
  • +1
9 Comments
 
LVL 1

Expert Comment

by:Paulmul
ID: 8195919
open (INFILE, ">abc.txt") || die "Can not open for reading: $!";

while ($line = <INFILE>) {  
               
             
        $position  = index($line,$search);

        if ($line == "Pls delete this line" ) {
     
     $line = "deleted succesfully";

     }    


close(INFILE);

#########################################

Something to that effect any way.

Paul
0
 
LVL 1

Expert Comment

by:Paulmul
ID: 8195983
I wrote this to search a cd archive. Similar principle to what you asked.

##########################################

 open (INFILE, "archive.txt") || die "Can not open for reading: $!";

 print("Enter the file name to search for\n");
     
 $search = <STDIN>;

 $search =~ s/\n//g;                #cut off end space

 $search = uc($search);

 print ("\n");                    #space after input

 
    $i = 0;

    while ($line = <INFILE>) {  
               
                     
     
        $position  = index($line,$search);

        if ($position > -1) {
                   
     @result[$i]= $line;
        $i++;
     
          }

     }
     
     print (@result);
         

close(INFILE);
0
 
LVL 2

Expert Comment

by:Itatsumaki
ID: 8196433
Personally I'd prefer to do it this way, but the above solutions are close to working for you, I think:

# Locals
my $deleted_flag = 0;

# File-handling
open(IN,  "<$infile");
open(OUT, ">temp0001.txt");

# File-processing
while (<IN>) {
    chomp();
    if (/Pls delete this line/) {
       $deleted_flag = 1;
       next();
       }
    else {
       print OUT;
       }
    }

# Summary line
if ($deleted_flag) {
     print OUT "Line was successfully deleted\n";
     }

# File-handling
close(IN);
close(OUT);
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 1

Expert Comment

by:Paulmul
ID: 8196472
That uses an out file which is unnecessary and a waste of system resources. If the line simply needs to be replaced there would still be the old file.

Paul
0
 
LVL 2

Expert Comment

by:Itatsumaki
ID: 8196977
Indeed, but to do that requires him to be able to lock the old file, which may or may not be possible.

This way he could add code like:

while (1) {
    if (!flock($infile, 2)) {
        sleep 15;
        }
    else {
        unlink($infile);
        rename($outfile, $infile);
        last();
        }
    }

So it's just safer, but less efficient.
Also if multiple matches are needed, he'll have to add a while-loop around the index() call.
 
0
 
LVL 26

Accepted Solution

by:
wilcoxon earned 200 total points
ID: 8197328
And another option:

use Fcntl qw(O_RDWR O_EXLOCK)
use Tie::File;

# tie the array @lines to the file abc.txt
# open for read/write and with an exclusive lock
# remove O_EXLOCK if you don't want or can't get an exclusive lock
tie @lines, 'Tie::File', 'abc.txt', mode => O_RDWR|O_EXLOCK;

# option 1 - not entirely sure grep works with a tied file
my $old_cnt = scalar @lines;
@lines = grep { !/Pls delete this line/ };
push @lines, "deleted successfully" unless ($old_cnt == scalar @lines);

# option 2
# now @lines is the file abc.txt
# could use grep instead of first or skip this check altogether
use List::Utils qw(first);
exit unless first /Pls delete this line/ @lines;
my $del = 0;
for my $i (0..@lines-1) {
    splice(lines, $i, 1), $del++ if ($lines[$i] =~ /Pls delete this line/);
}
push @lines, 'deleted successfully' if $del;
0
 

Author Comment

by:abc88
ID: 8215039
Hi Wilcoxon,

I downloaded Fcntl.pm, Tie/File.pm, XSLoader.pm and DynaLoader.pm from internet and located it in /pgfs5/eng/ayeoh2/pl/pm
 and I tried:

use lib "/pgfs5/eng/ayeoh2/pl/pm";
use Fcntl qw(O_RDWR O_EXLOCK);
use Tie::File;

tie @lines, 'Tie::File', 'abc.txt', mode => O_RDWR|O_EXLOCK;

my $old_cnt = scalar @lines;
@lines = grep { !/Pls delete this line/ };
push @lines, "deleted successfully" unless ($old_cnt == scalar @lines);

The errors below prompted out:

Can't declare undef operator in my at /pgfs5/eng/ayeoh2/pl/pm/Fcntl.pm line 207, near ") ="
BEGIN failed--compilation aborted at try.pl line 4.

I am not familiar with these perl module. Pls advice.

0
 

Author Comment

by:abc88
ID: 8215062
I then comment out line:

 my (undef,$file,$line) = caller; <line 207 in Fcntl.pm>

and replace:

  (undef,$file,$line) = caller;

it show me the error:

&Fcntl::constant not defined at /pgfs5/eng/ayeoh2/pl/pm/Fcntl.pm line 204.
BEGIN failed--compilation aborted at try.pl line 4.
0
 
LVL 26

Expert Comment

by:wilcoxon
ID: 8215189
I'm not sure what the problem is unless there is a version mismatch.  You should not have needed to download most of those.

Fcntl, XSLoader, and DynaLoader are part of the perl core dating back at least to 5.004 (the earliest I can check on www.perldoc.com).

Tie::File was made part of the core in 5.8.

Try deleting the modules that you put under /pgfs5/eng/ayeoh2/pl/pm (except Tie::File unless you are using perl 5.8).

If you have a perl older than 5.005, I would strongly encourage you to upgrade.
0

Featured Post

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

I've just discovered very important differences between Windows an Unix formats in Perl,at least 5.xx.. MOST IMPORTANT: Use Unix file format while saving Your script. otherwise it will have ^M s or smth likely weird in the EOL, Then DO NOT use m…
Many time we need to work with multiple files all together. If its windows system then we can use some GUI based editor to accomplish our task. But what if you are on putty or have only CLI(Command Line Interface) as an option to  edit your files. I…
Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…
Six Sigma Control Plans
Suggested Courses

762 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question