1

Как бы я удалил строку

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

из файла командой perl в сценарии ksh?

Я старался:

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

Но я получил:

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

3 ответа3

1

[ , . , и / имеют особое значение в регулярном выражении. Вы должны избежать их:

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

РЕДАКТИРОВАТЬ: имейте в виду, что это не удалит строку, а просто удалит текст, который есть в регулярном выражении. Если это целая строка, то пустая строка останется.

Более читаемая версия (используйте квадратные скобки, чтобы определить регулярное выражение, чтобы вам не пришлось экранировать /):

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

Но, поскольку вы спрашиваете о сценарии оболочки, зачем использовать Perl, а не grep -v (--invert-match)?

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

Файл до

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

Команда (использование \Q, чтобы игнорировать особенность специальных символов в регулярном выражении)

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

Файл после

$ cat t.txt
aaa
bbb

Замечания:
Измените -i на -i.bak если вы хотите, чтобы perl сделал резервную копию файла перед изменениями.

Вы также можете сделать это таким образом (с помощью простого теста на равенство текста, без регулярных выражений).

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

Я думаю, что у меня есть кое-что, что будет работать для вас, в основном я читаю в текущем файле и вывожу "измененную" версию файла минус соответствующая строка (та, которая упоминается в вопросе). Кажется, это работает для меня, когда я проверяю это. Пожалуйста, НЕ ПЫТАЙТЕСЬ, пока не сделаете резервную копию на случай, если что-то пойдет не так.

вот код, измените имя файла в соответствии с вашими потребностями, затем запустите скрипт, который "должен" работать.

Это не очень красиво, но это работает.

#!/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;

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .