Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

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/Li.ksh//" /etc/tl.conf 

But I got:

Unmatched [ in regex; marked by <-- HERE in m/[ <-- HERE [ -f / at -e line 1.
share|improve this question
add comment

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
share|improve this answer
    
I not want to write to other file as /etc/tl.conf , I want to edit only file /var/tmp/tl.conf , about the perl seems good but I need simpler option , you used "\" many time in the lines ! –  diana Nov 16 '11 at 9:07
    
@diana Ok then just escape the special characters as suggested. –  Matteo Nov 16 '11 at 9:10
    
maybe you have some other trick in perl in order not to use the "\" ? –  diana Nov 16 '11 at 9:11
    
@diana There a couple of tricks but in general you have to escape special characters if you want to use a regular expression. –  Matteo Nov 16 '11 at 9:12
1  
@diana, @Matteo: You can use \Q to escape all following special characters. This avoids the need for inserting all those `\` characters. –  RedGrittyBrick Nov 16 '11 at 10:59
show 2 more comments

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;
share|improve this answer
add comment

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
share|improve this answer
    
+1 for both eq and \Q –  glenn jackman Nov 16 '11 at 14:29
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.