私は次のようにレイアウトされた設定ファイルの変更をスクリプト化しています:
[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]のみのワンライナーを作成することは可能ですか?
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
構成が_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]
_に置き換えるように指示しています。 _[
_と_]
_は通常、正規表現で特別な意味を持つため、エスケープする必要があります。
このawkソリューションを試すことができますか
awk '/shovel/{flag=1}flag&&/enabled/{$NF=1;flag=0}1' input
sed
を特定の行の変更のみに制限できます。
sed -i '3s/enabled = 0/enabled = 1/g' file
これにより、[紫]の3行目のみが変更されます。