\s
не принимается, потому что вы используете строку в двойных кавычках. Строка в двойных кавычках пытается понять смысл \s
и не знает, что с ней делать, вы можете сказать что-нибудь из следующего, чтобы она работала:
"\\s+seqfile\\s+=\\s+[a-z]+.."
'\s+seqfile\s+=\s+[a-z]+..'
qr/\s+seqfile\s+=\s+[a-z]+../
Последняя является предпочтительной формой, потому что она создает скомпилированное регулярное выражение, которое будет быстрее обычной строки. Скомпилированное регулярное выражение преобразуется в строку, если вы используете его в контексте, который не ожидает регулярного выражения, поэтому вы можете сказать
print "$find\n";
и вернитесь (?-xism:\s+seqfile\s+=\s+[a-z]+..)
.
Кроме того, если вы собираетесь отрицать класс символов, вы должны поместить курсор в класс символов: [^a-zA-Z0-9]
означает не буквенно-цифровой (по крайней мере, для ASCII), но ^[a-zA-Z0-9]
означает совпадение буквенно-цифрового в начале строка (или начало строки, если установлена опция /m
).
Кроме того, когда файл открывается в режиме >>
, вы не можете прочитать его. Я изменил ваш код для чтения из STDIN (или файлов в командной строке) и записи в STDOUT. Это стандартная техника Perl, называемая фильтрацией. Позволяет строить конвейеры программ. Вы можете запустить скрипт так:
./script.pl inputfile > outputfile
или это
cat inputfile | ./script.pl > outputfile
Вот сценарий
#!use/bin/perl
use strict;
use warnings;
my $find = qr{ \s+ seqfile \s+ = \s+ [a-z]+ .. }x;
my $replace = "done";
while (<>) {
s/$find/$replace/g;
print;
}
Это также может быть сведено к одной строке:
perl -pe 's/\s+seqfile\s+=\s+[a-z]+../done/g' inputfile
Хорошие источники для изучения регулярных выражений: