How do I delete a certain line from a file with Perl?

How would I delete the line

[[ -f /var/tmp/Li.ksh ]] && /var/tmp/Li.ksh

from a file by a perl command in a ksh script?

I tried:

perl -i -pe "s/[[ -f /var/tmp/Li.ksh ]] && /var/tmp/" /etc/tl.conf 

But I got:

Unmatched [ in regex; marked by <-- HERE in m/[ <-- HERE [ -f / at -e line 1.

3 Answers

[, ., and / have a special meaning in a regular expression. You have to escape them:

perl -i -pe "s/\[\[\ -f\ \/var\/tmp\/Li\.ksh\ \]\]\ &&\ \/var\/tmp\/Li\.ksh//" 

EDIT: beware that this will not delete the line but just remove the text you have in the regex. If if it the whole line a blank line will remain.

More readable version (use brackets to define the regex so that you don't have to escape /):

perl -i -pe "s{\[\[ -f /var/tmp/Li.ksh \]\] && /var/tmp/Li\.ksh}{}"

But, since you are asking about a shell script, why use Perl and not grep -v (--invert-match)?

grep -v '[[ -f /var/tmp/Li.ksh ]] && /var/tmp/Li.ksh' /etc/tl.conf
7

File before

$ cat t.txt
aaa
[[ -f /var/tmp/Li.ksh ]] && /var/tmp/Li.ksh
bbb

Command (using \Q to ignore the specialness of special characters in the regular expression)

$ perl -i -lne 'print unless m{\Q[[ -f /var/tmp/Li.ksh ]] && /var/tmp/Li.ksh}' t.txt

File after

$ cat t.txt
aaa
bbb

Note:
Change -i to -i.bak if you want perl to make a backup of the file before the changes.

You can also do it this way (using simple text equality test, no regex).

$ perl -i -lne 'print unless $_ eq q([[ -f /var/tmp/Li.ksh ]] && /var/tmp/Li.ksh)' t.txt
1

I think I got something that will work for you, basicly I am reading in the current file and outputting a "modified" version of the file minus the matching line (the one mentioned in the question). It seems to work for me when I test it. Please Please DO NOT try this until you make a backup just in case it goes wrong.

here is the code, change the file name to suit your needs then run the script it "should" work.

Its not very pretty but it works.

#!/usr/bin/perl
use strict;
use warnings;
my $in_file = "sample.txt";
my $out_file = "control.txt";
open INFILE , "<", $in_file;
open OUTFILE, ">", $out_file;
my @array;
while (<INFILE>) { push @array, $_;
}
foreach my $line (@array) { if ( $line =~ /(\"\[\[\s*\-f\s*\/var\/tmp\/Li\.ksh\s*\]\]\s*\&\&\s*\/var\/tmp\/Li.ksh\")/xm ) { print "I have ommited the following line $1\n"; } else { print OUTFILE "$line"; }
}
close INFILE;
close OUTFILE;

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

You Might Also Like