
だからこんなファイルがあります。
[ABC]
value1=bla
value2=bla
value3=bla
[XYZ]
value1=bla
value2=bla
value3=bla
[ABC]ブロックの下のvalue1を[XYZ]ブロックの下のvalue1の代わりに "value1 = notbla"に置き換えたいと思います。私はすでに試しました。
sed '/ABC/{n;s/.*/change/}' file
ただし、これは次の行に移動しようとした場合にのみ機能し、特定のパターンを変更しません(たとえば、value1がvalue2より低い場合)。特定の行番号がわからない場合は、どのsedまたはawkコマンドを使用できますか?使用されている各sedタグまたはawkタグの機能を表示できますか?誠にありがとうございます。
答え1
sedはこれを簡単に処理できます。これは、アドレス範囲が接頭辞で付けられる単一の「交換」コマンドです。読みやすくするために、追加の間隔を追加しました。
sed -e '/^\[ABC\]$/ , /^\[.*\]$/ s/^\(value1=\).*$/\1notbla/'
追加の間隔がない場合は、次のようになります。
sed -e '/^\[ABC\]$/,/^\[.*\]$/s/^\(value1=\).*$/\1notbla/'
実際に正規表現を固定する必要はありませんが、異常な入力がある場合にはより安全です。固定されていない正規表現を使用する少し短いバージョンは次のとおりです。
sed -e '/\[ABC\]/,/^\[/s/^\(value1=\).*$/\1notbla/'
説明する:
各フラグやオプションの説明を求められました。上記の3つのSedコマンドの最終(最も短い)バージョンについて説明しています。
行の最初の部分はアドレス範囲です。アドレス範囲の後の代替/startregex/,/stopregex/
コマンドは、〜から(含む)までの行s
にのみ適用されます。startregex
stopregex
この場合、開始正規表現はです/\[ABC\]/
。角かっこは通常正規表現の特殊文字なので、リテラル角かっこ文字を表すために各文字の前にバックスラッシュを追加します。
正規表現を停止することは、/^\[/
特殊な正規表現文字を使用して行^
の先頭を表示することです。このパターンは、開いている[
括弧()で始まるすべての行と一致します。
代替コマンドはs
基本的に非常に簡単です。一般的な形式はですs/findregex/replacetext/
。また、アクションを修正するためにFinalの後ろに特別なフラグを入れることもできますが、/
ここではそのようなフラグを使用しませんでした。
「正規表現を探す」はです^\(value1=\).*$
。
^
前述のように、カラット()は行の先頭と一致し、ドル記号($
)は行の終わりと一致します。したがって、パターン全体は、ラインの一部ではなくライン全体と一致する必要があります。
()
角括弧()は角括弧とは異なりいいえ-specialは基本的に正規表現で特別なので、特別な意味を与えるためにバックスラッシュを先頭に追加します。部分一致テキスト(正規表現検索に一致するテキスト)を代替テキストに使用できます。具体的には、\1
テキストで置き換えるとは、「正規表現の最初の角かっこセット内で一致するテキスト」を意味します。この場合、常に「value1 =」です。
「正規表現の検索」の最後の要素はです.*
。点(.
)は「すべての単一文字」を意味し、アスタリスク(*
)は「任意の回数(0個以上)」を意味します。したがって、点線のアスタリスク(.*
)は、等号の後の残りの行全体と一致します。
代替テキストの「notbla」は、特別な内容ではなく静的テキストにすぎません。
Sedを正しく学ぶには強くお勧めしますGrymoire Sed チュートリアル、オンラインで無料です。
答え2
awk '
BEGIN {FS=OFS="=";}
/\[.*\]/ {if ($0 == "[ABC]") edit=1; else edit=0;}
{if (edit && $1 == "value1" ) $2="notbla";}1
' file
答え3
別のawk
ソリューション
$ cat ip.txt
[ABC]
value1=bla
value2=bla
value3=bla
[XYZ]
value1=bla
value2=bla
value3=bla
行が[
指定されたフラグで始まる場合、そのフラグはブロック名に従って設定または消去されます。その後、フラグがセットされたら交換します。
$ awk '/^\[/{f=/\[ABC\]/} f{sub("value1=bla","value1=nobla")} 1' ip.txt
[ABC]
value1=nobla
value2=bla
value3=bla
[XYZ]
value1=bla
value2=bla
value3=bla
の同様のソリューションがperl
デモの代替に変更されました。
$ perl -pe '$f=/\[ABC\]/ if /^\[/; s/value2=bla/value2=nobla/ if $f;' ip.txt
[ABC]
value1=bla
value2=nobla
value3=bla
[XYZ]
value1=bla
value2=bla
value3=bla
=
特定の一致に関係なく、右側のすべての項目を変更する必要がある場合は、bla
次を使用してください。
awk '/^\[/{f=/\[ABC\]/} f{sub(/value1=.*/,"value1=nobla")} 1' ip.txt
perl -pe '$f=/\[ABC\]/ if /^\[/; s/value2=.*/value2=nobla/ if $f;' ip.txt