파일의 두 정규식 패턴 사이에서 줄을 점진적으로 교환합니다.

파일의 두 정규식 패턴 사이에서 줄을 점진적으로 교환합니다.

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(개행), 변수를 변경합니다 a.

답변4

POSIX sed 구조를 사용하여 위 줄을 뒤집을 수 있습니다.

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

관련 정보