Многострочное совпадение Perl для «чего-то», начинающегося без «#\s»

Многострочное совпадение Perl для «чего-то», начинающегося без «#\s»

ОБНОВЛЯТЬ:

  1. РЕАЛЬНЫЙ ответ на этот МНОГОСТРОЧНЫЙ вопрос дал Стефанhttps://unix.stackexchange.com/a/521560/354415
  2. В качестве альтернативы можно воспользоваться кодом perl от Terdon, который представлен ниже:https://unix.stackexchange.com/a/521512/354415
  3. В качестве альтернативы я могу самостоятельно изучить IFS построчно:https://unix.stackexchange.com/a/521550/354415

Вот моя новая игрушка:

Проблема в том, что я хочу, чтобы он соответствовал только тем строкам, в которых нет #\s* перед параметром.

Пожалуйста, не предоставляйте альтернативный код, например sed и т.п., используйте perl

perl -we 'my $file= "parameter=9
# parameter=10
parameter=10
"; $file=~ s/.*((?<!^# ))parameter\s*=.*/parameter=replaced/g; print(":$file:\n")'

Ожидаемый результат

parameter=replaced
# parameter=10
parameter=replaced

P.S. Если вам интересно узнать, как я продвигался в этом направлении, посмотрите здесь:Может быть, Perl Negative Lookbehind с обходом переменной длины?

решение1

Это осложняется вашим выбором передать многострочную строку как одну переменную. гораздо проще просто преобразовать ее в массив, чтобы можно было использовать оператор s///в его простейшей форме. Попробуйте это: вы сказали, что вас не интересуют улучшения кода, но чтобы помочь будущим пользователям, вот упрощенная версия того, что вы написали, которая также избегает плохой практики использования ALLCAPS для переменных, не относящихся к окружению:

newparameter='parameter=replaced'
filesection='
   parameter=9
# parameter=10
parameter=10
'

matchparamperl='^([^#]*)parameter\s*=.*'

sectionfixed=$( perl -le '
                         @lines=split(/\n/,$ARGV[0]);
                         s/$ARGV[1]/$1$ARGV[2]/g for @lines; 
                         print join "\n", @lines
                         ' "$filesection" "$matchparamperl" "$newparameter") 
echo "$sectionfixed"

Это вернет:

$ echo "$sectionfixed"

   parameter=replaced
# parameter=10
parameter=replaced

Или немного короче:

sectionfixed=$( perl -le '
                         do{
                            s/$ARGV[1]/$1$ARGV[2]/g; print
                         } for split(/\n/,$ARGV[0])
                         ' "$filesection" "$matchparamperl" "$newparameter")

решение2

perl -we 'my $file= "parameter=9
# parameter=10
parameter=10
"; $file=~ s/.*((?<!# ))parameter\s*=.*/parameter=replaced/g; print(":$file:\n")'

Вот как это делается )))

Выход:

parameter=replaced
# parameter=10
parameter=replaced

Называется «Отрицательный взгляд назад» http://www.blackwasp.co.uk/RegexLookahead.aspx

Спасибо Кусалананде за идею.

Я бы никогда об этом не подумал.

решение3

contents='
   parameter=9
# parameter=10
parameter=10
'

sed '/^#/!s/parameter[[:blank:]]*=.*/parameter=replaced/' <<<"$contents"

Выход:

   parameter=replaced
# parameter=10
parameter=replaced

Код sedпросто применяет замену ко всем строкам, не начинающимся с #символа.

Связанный контент