
アップデート:
- このマルチラインの質問に対する本当の答えは、ここでステファンによって与えられましたhttps://unix.stackexchange.com/a/521560/354415
- あるいは、以下の Terdon による perl で行ごとに実行します。https://unix.stackexchange.com/a/521512/354415
- あるいは、ここで IFS を 1 行ずつ自分で実行します。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
PS: 私がこれをどのように進めたかに興味があるなら、こちらをご覧ください:可変長バイパスによる Perl 否定後読みでしょうか?
答え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
アイデアを提供してくれたKusalanandaに感謝します。
そんなことは決して思いつかなかったよ。
答え3
contents='
parameter=9
# parameter=10
parameter=10
'
sed '/^#/!s/parameter[[:blank:]]*=.*/parameter=replaced/' <<<"$contents"
出力:
parameter=replaced
# parameter=10
parameter=replaced
このsed
コードは、文字で始まっていないすべての行に置換を適用するだけです#
。