저는 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위에서 언급한 다른 응용 프로그램의 경우.