web-dev-qa-db-ja.com

パターンを一致させ、それに続く文字列の最初のインスタンスを置き換えます

私は次のようにレイアウトされた設定ファイルの変更をスクリプト化しています:

[purple]
auth = no
enabled = 0
username = 
password =
priority = 0
Host = True

[shovel]
group = 
manual = False
enabled = 0
username = 

多くの[カテゴリ]があり、キーと値のペアの同じキーを持つ場合もあります。

Awk/sed/grep/tr/cut/Perlを使用して、「enabled = 0」の値を「enabled = 1」に変更できるが、カテゴリ[shovel]のみのワンライナーを作成することは可能ですか?

3
user1930831

sedでは、範囲を使用できます([shovel]カテゴリの最後の空の行で停止します)。

sed '/\[shovel\]/,/^$/ s/enabled = 0/enabled = 1/' file

最初の部分/\[shovel\]/,/^$/は、[shovel]の行を見つけ、空の行が見つかるまで続行し、次のコマンド(この場合は単純なs/old/new)を実行することを意味します。 fileのその部分

コメントへの応答に注意してください:sedは、範囲とアドレスの代替区切り文字を受け入れません(したがって、それらに一致する必要がある場合は、リテラルである必要がある/文字をエスケープします)。バックスラッシュ。次のコマンドでは、いつでも代替の区切り文字を使用できます。次に例を示します。

sed '/\[shovel\]/,/^$/ s|enabled = 0|enabled = 1|' file

または

sed '\|\[shovel\]|, |^$| s|enabled = 0|enabled = 1|' file
5
Zanna

構成が_config.ini_にあると仮定して、Perlを使用したソリューションを次に示します。

_Perl -000 -n -i -e 's/^enabled = 0$/enabled = 1/m if /^\[shovel\]\n/; print;' config.ini
_

これは次のことを行います。

  • _-000_-段落モードでファイルを読み取ります。これは、コードで_$/ = "\n\n";_を実行するのと基本的に同じです。
  • _-n_-while (<>) { }ループ内で指定されたコードを実行します。
  • _-i_-標準出力に出力する代わりに、指定されたファイルをインライン編集します。オプションで拡張子を指定できます。これにより、入力ファイルがその拡張子でバックアップされます。たとえば、_-i.bak_は_config.ini.bak_というバックアップファイルを作成します。
  • _-e_-指定されたPerlコードを実行します。

コード自体は、入力「段落」が行自体で_enabled = 0_で始まる場合、正確に_enabled = 1_を含む行を_[shovel]_に置き換えるように指示しています。 _[_と_]_は通常、正規表現で特別な意味を持つため、エスケープする必要があります。

0

このawkソリューションを試すことができますか

awk '/shovel/{flag=1}flag&&/enabled/{$NF=1;flag=0}1' input
0
Kamaraj

sedを特定の行の変更のみに制限できます。

 sed -i '3s/enabled = 0/enabled = 1/g' file

これにより、[紫]の3行目のみが変更されます。

0
Tom Kelly