파일의 두 정규식 패턴 사이에서 점진적으로 줄 바꾸기

파일의 두 정규식 패턴 사이에서 점진적으로 줄 바꾸기

Bash 스크립트를 사용하여 파일에 대한 일부 텍스트 처리를 수행하려고 합니다. 목표는 'attribute:' 라벨 아래에 들여쓰기된 "field:"로 시작하는 모든 줄을 가져와서 그 뒤에 나오는 "- attr:"로 시작하는 관련 줄로 바꾸는 것입니다.

지금까지 레이블과 일치해야 하는 정규식 패턴이 있다고 생각합니다.

/ *field:(.*)/g

/ *- attr:(.*)/g

그러나 원하는 필드를 구문 분석하고 올바르게 교체하는 논리에는 성공하지 못했습니다.

입력 텍스트 예

- metric: 'example.metric.1'
  attributes:
      field: 'example 1'
    - attr: 'example1'
      field: 'example 2'
    - attr: 'example2'
      field: 'example 3'
    - attr: 'example3'
      field: 'example 4'
    - attr: 'example4'
- metric: 'example.metric.2'
  attributes:
      field: 'example 5'
    - attr: 'example5'
      field: 'example 6'
    - attr: 'example6'
      field: 'example 7'
    - attr: 'example7'
- metric: 'example.metric.3'
...

원하는 출력

- metric: 'example.metric.1'
  attributes:
    - attr: 'example1'
      field: 'example 1'
    - attr: 'example2'
      field: 'example 2'
    - attr: 'example3'
      field: 'example 3'
    - attr: 'example4'
      field: 'example 4'
- metric: 'example.metric.2'
  attributes:
    - attr: 'example5'
      field: 'example 5'
    - attr: 'example6'
      field: 'example 6'
    - attr: 'example7'
      field: 'example 7'
- metric: 'example.metric.3'
... 

이 작업을 수행하려면 어떻게 해야 합니까?

답변1

모든 Unix 상자의 모든 쉘에서 awk를 사용하십시오.

$ awk '$1=="field:"{s=ORS $0; next} {print $0 s; s=""}' file
- metric: 'example.metric.1'
  attributes:
    - attr: 'example1'
      field: 'example 1'
    - attr: 'example2'
      field: 'example 2'
    - attr: 'example3'
      field: 'example 3'
    - attr: 'example4'
      field: 'example 4'
- metric: 'example.metric.2'
  attributes:
    - attr: 'example5'
      field: 'example 5'
    - attr: 'example6'
      field: 'example 6'
    - attr: 'example7'
      field: 'example 7'
- metric: 'example.metric.3'

일부 줄 뒤에 공백이 없거나 field:어떤 이유로 정규식을 사용하고 싶은 욕구가 있다면 또는 중 원하는 것으로 $1=="field:"변경 하세요.$1~/^field://^[[:space:]]*field:/

답변2

와 함께 sed:

sed -n '/^ *field: /{h;n;G};p' data

키워드 가 일치하면 field다음과 같습니다.

  • 현재 줄을 hold space( h) 안에 저장
  • pattern space( n) 안의 파일에서 다음 줄을 가져옵니다.
  • ( ) pattern space로 교환 (라인 교환과 동일)hold spaceG

만나는 각 줄을 인쇄하십시오.p

답변3

사용 awk:

awk '{if ($1 == "field:") {a=$0;x=0} 
else if (/- attr:/) {$0 = $0 ORS a; x=1} else {x=1}}x' input

이 명령에서 가 field:발견되면 현재 입력 레코드( $0)가 변수에 저장되고 ax는 0으로 설정됩니다. 그리고 attr:가 발견 되면 $0d를 old로 변경 $0하고 그 뒤에 ORS(newline) 다음에 변수를 붙입니다 a.

답변4

POSIX sed 구성을 사용하여 해당 라인을 뒤집을 수 있습니다.

sed '/attr:/!x;$G' file

관련 정보