sed를 사용하여 여러 줄의 텍스트 범위를 사용하여 범위 내의 문자열 바꾸기

sed를 사용하여 여러 줄의 텍스트 범위를 사용하여 범위 내의 문자열 바꾸기

내 파일(values.yaml)에 다음 콘텐츠가 있습니다.

global:
  repo1:
    enabled: true
  repo2:
    enabled: true

repo1:
  replicaCount: 1
  image:
    tag: latest
    pullPolicy: Always

repo2:
  replicaCount: 1
  image:
    tag: latest
    pullPolicy: Always

tag: latest나는 repo1을 이와 같은 것으로 바꾸고 tag: newest1repo2 tag: latest를 이와 같은 것으로 바꾸고 싶습니다 tag: newest2.

global:
  repo1:
    enabled: true
  repo2:
    enabled: true

repo1:
  replicaCount: 1
  image:
    tag: newest1
    pullPolicy: Always

repo2:
  replicaCount: 1
  image:
    tag: newest2
    pullPolicy: Always

그래서 해당 범위에서 하나의 태그만 가져와서 교체할 수 있도록 파일부터 파일 끝까지의 repo1:\n replicaCount:1범위 를 검색해 보려고 합니다 .pullPolicy

나는 가지고있다

sed -i "" "N;/repo1:\n  replicaCount:/,/pullPolicy/s/tag:.*/tag: newest1/g" values.yaml

그 다음에거의작동하지만 항상 마지막 pullPolicy줄을 제거합니다. 예를 들면 다음과 같습니다.

global:
  repo1:
    enabled: true
  repo2:
    enabled: true

repo1:
  replicaCount: 1
  image:
    tag: newest1
    pullPolicy: Always

repo2:
  replicaCount: 1
  image:
    tag: newest2

저는 Mac을 사용하고 있기 때문에 큰따옴표가 모두 붙어 있습니다.

끝 범위를 파일 끝(나도 시도했지만 $소용 없음) 또는 pullPolicy로 지정하는 방법은 무엇입니까?

답변1

sed -z개행 대신 널 문자 구분 기호를 사용하십시오.

cat values.yaml | sed -z "s/\nrepo\([0-9]*\):\n\(\([^\n]\+\n\)*\)\([ \t]*\)tag:[^\n]*/\nrepo\1:\n\2\4tag: new\1/g"

당신이 원하는 것을하십시오.

  • \nrepo\([0-9]*\):\n로 시작하는 줄을 일치시키고 repo해당 값을 에 기록합니다 \1.

  • \(\([^\n]\+\n\)*\)비어 있지 않은 행( \+최소 한 문자 이상)을 일치시키고 해당 값을 에 기록합니다 \2. \3내부 커뮤니티에는 낭비입니다.

  • \([ \t]*\)tag:[^\n]*tag공백으로 들여쓰기된 단어가 포함된 줄을 찾습니다.

  • \nrepo\1:\n\2\4첫 번째 줄은 변경하지 않고 그대로 둡니다.

  • tag: new\1new태그 값을 변경하려면 + repo 값을 사용하세요.

  • /g단일 명령으로 두 가지 변경을 모두 수행하는 데 사용됩니다.

작동하지 않으면 gnu-sed기본 sed.

답변2

sed -ri ':1;/^repo[12]/,/tag/!b;/tag/!{N;b1};s/^(repo(.).*)latest$/\1newest\2/'

잊지 마요현재 버퍼의 내용을 표시하는 디버깅에 사용되는 명령입니다. 예를 들어:

sed -nr ':1;/^repo[12]/,/tag/!b;/tag/!{N;b1};l;s/^(repo(.).*)latest$/\1newest\2/' file

repo1:\n  replicaCount: 1\n  image:\n    tag: latest$
repo2:\n  replicaCount: 1\n  image:\n    tag: latest$

생산:

sed -ri '/^repo[12]/!b;:1;/tag/!{N;b1};s/^(repo(.).*)latest$/\1newest\2/' file

답변3

이 파일을 편집 하는 방법 python은 yaml 모듈을 가져온 다음 yaml 파일을 Python 사전(해시 |라고도 함)에 로드하는 것입니다. 중첩 배열이기는 하지만 연관 배열입니다.

그런 다음 yaml 파일의 키 값을 조정합니다.

마지막으로 사전을 다시 yaml 파일에 저장합니다.

sed 코드는 yaml 파일의 최상위 노드에 빈 줄을 삽입합니다.

$ yaml_file='values.yaml'

$ python3 - "$yaml_file" <<\YAML
import sys, yaml

yaml_doc = sys.argv[1]

with open(yaml_doc) as fp:
  h = yaml.safe_load(fp)

h['repo1']['image']['tag'] = 'newest1'
h['repo2']['image']['tag'] = 'newest2'

with open(yaml_doc, 'w') as fp:
  yaml.safe_dump(h, fp, default_flow_style=False)
YAML

$ sed -Ei -e '1!{/^\S/{H;z;x;};}' "$yaml_file" 

관련 정보