외부 도구를 사용하지 않고 yaml 파일 구문 분석

외부 도구를 사용하지 않고 yaml 파일 구문 분석

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

관련 정보