私はBashを初めて使用するときにyamlファイルでいくつかの動的パラメータを更新する必要があるという問題に遭遇しました。
クエリ()によると、search4.subsearch1.name
更新する必要があります。
name: old_name
入力する
name: new_name
- サンプルファイルは次のとおりです。
search1: name: name1 pass: pass1 date: date1 #these are just commented texts search2: #Adding few more commented lines myname: somename name: name2 pass: pass2 someotherparam: param1 search3: nameAndSurname: NS namingConv: true varSet: P3 search4: #Again adding some special name: strings here myname: somename1 name: new_name pass: new_pass ptherparam1: T3 subsearch1: #Again adding some special name strings here myname: somename2 name: old_name pass: pass2 ptherparam1: param3 search5: #Again adding some special name strings here var1: value1 name: some_name pass: some_pass
したがって、クエリ()に基づいて次にsearch4.subsearch1.name
更新する必要があります。name: old_name
name: new_name
- 予想出力:
search4: #Again adding some special name: strings here myname: somename1 name: new_name pass: new_pass ptherparam1: T3 subsearch1: #Again adding some special name strings here myname: somename2 name: new_name pass: pass2 ptherparam1: param3
試してみましたがawk
成功sed
しませんでした。
lineNR=$(awk "/\<search4:/{f=1} f && /\<name:/ {print NR; exit}" testfile.txt);sed "${lineNR}s/name.*/name: new_name/" testfile.txt
答え1
あなたが持つことができると仮定マイクパラyq
ダウンロードしてインストールすると、プロセスが簡単になります。
yq eval '.search4.subsearch1.name = "new_name"' file.yml
私はあなたが言ったことに気づきました。コメントそれ」私たちはインターネットに接続されておらず、対応するLinuxボックスには外部パッケージは許可されていません。自分自身がパッケージを追加できない場合でも、これらのシステムにソフトウェアを追加するように要求する管理プロセスがあります。「変更要求」かもしれません。サポートしやすい
テストのためにインデントが入っていることを確認するためにコンテンツを編集する必要がありましたsearch4
。質問自体の内容を編集したわけではありません。
答え2
どのシステムを使用しているのか、インストールしたのか教えてくれませんでした。したがって、これは単に教育された推測です。多くのLinuxディストリビューションには「python」が付属しており、yamlの増加は、このディストリビューションが「pyaml」ライブラリとともにインストールされることが多いことを意味します。 yamlファイルと直接対話するという事実は、このシナリオの可能性を高めます。
これを非常に簡単にテストできます。次の内容のみを含むファイルを作成しますfoo.py
。
import yaml
print("I have yaml")
次に、コマンドラインから実行します。
python3 foo.py
単に印刷する場合は、pythonとpyamlがインストールされており、単純なスクリプト()I have yaml
で使用できます。update_script.py
import yaml
import sys
# Load the file into a data structure
with open(sys.argv[1], "r") as file:
content = yaml.safe_load(file)
# Update the key you want to change
content["search4"]["subsearch1"]["name"] = "new_name"
# Write the data structure back to your file in YAML
with open(sys.argv[1], "w") as file:
yaml.safe_dump(content, file)
次に、次を実行します。
python3 update_script.py config_file.yaml
答え3
すべてのUnixシステムのすべてのシェルでawkを使用してください。
$ cat tst.awk
NF && !/^[[:space:]]*#/ && match($0,/^[[:space:]]*/) {
prevIndent = currIndent
currIndent = RLENGTH
name = $1
sub(/:.*/,"",name)
if ( currIndent == 0 ) {
path = name
}
else {
if ( currIndent <= prevIndent ) {
sub(/\.[^.]+$/,"",path)
}
path = path "." name
}
if ( path == tgt ) {
$0 = substr($0,1,currIndent) $1 " " val
}
}
{ print }
$ awk -v tgt='search4.subsearch1.name' -v val='new_name' -f tst.awk file
search1:
name: name1
pass: pass1
date: date1
#these are just commented texts
search2:
#Adding few more commented lines
myname: somename
name: name2
pass: pass2
someotherparam: param1
search3:
nameAndSurname: NS
namingConv: true
varSet: P3
search4:
#Again adding some special name: strings here
myname: somename1
name: new_name
pass: new_pass
ptherparam1: T3
subsearch1:
#Again adding some special name strings here
myname: somename2
name: new_name
pass: pass2
ptherparam1: param3
search5:
#Again adding some special name strings here
var1: value1
name: some_name
pass: some_pass
上記はYAMLパーサーではなく、表示された例と同じ構造を持つファイルに対してのみ機能し、すべてのインデントはタブまたはスペースですが、両方ではありません。
バラよりhttps://stackoverflow.com/questions/66173552/update-yaml-value-on-cli#comment116993514_66173552上記の他のアプリケーションの場合。