sed: 패턴 뒤에 일치하는 줄을 이동하시겠습니까?

sed: 패턴 뒤에 일치하는 줄을 이동하시겠습니까?

구성 파일이 있습니다 .drone.yml.

workspace:
  base: x
  path: y

pipeline:
  import-groups-check:
    pull: true

  static-check:
    pull: true

  build:
    image: golang:1.9.0

  publish:
    image: plugins/docker:1.13

  validate-merge-request:
    pull: true

  notify-youtrack:
    pull: true

validate-merge-request내가 원하는 것은 첫 번째 단계 로 이동하는 것입니다 .

workspace:
  base: x
  path: y

pipeline:
  validate-merge-request:
    pull: true

  import-groups-check:
    pull: true

  static-check:
    pull: true

  build:
    image: golang:1.9.0

  publish:
    image: plugins/docker:1.13

  notify-youtrack:
    pull: true

다음과 같은 방법을 사용하여 단계를 추출할 수 있다는 것을 알고 있습니다 validate-merge-request.

sed -e '/validate-merge-request/,/^ *$/!{H;d;}'

이후로 어떻게 이동할 수 있나요 pipeline:?

답변1

앞쪽:

sed -e '
  # From first line to pipeline:,just print and start next cycle
  1,/^pipeline:$/b
  # With all lines outside validate-merge-request block, push to hold space,
  # delete them and start next cycle
  # On last line, exchange hold space to pattern space, print pattern space
  /validate-merge-request/,/^$/!{
    H
    ${
      x
      s/\n//
      p
    }
    d
  }' <file

pipeline:블록 뒤와 블록 내부가 아닌 모든 행은 validate-merge-request메모리에 유지됩니다.

답변2

지도는 본질적으로 순서가 없습니다. 파이프라인 데이터를 정렬하려면 시퀀스가 ​​필요합니다.

workspace:
  base: x
  path: y
pipeline:
- import-groups-check:
    pull: true
- static-check:
    pull: true
- build:
    image: golang:1.9.0
- publish:
    image: plugins/docker:1.13
- validate-merge-request:
    pull: true
- notify-youtrack:
    pull: true

분명히 이것은 현재 YAML 파일을 처리하는 방법에 영향을 미칩니다.

변경하는 경우 다음을 수행할 수 있습니다.

ruby -e '
  require "yaml"
  data = YAML.load(File.read ARGV.shift)
  idx = data["pipeline"].find_index {|elem| elem.has_key? "validate-merge-request"}
  data["pipeline"].unshift( data["pipeline"].delete_at idx )    
  puts YAML.dump(data)
' .drone.yml

어느 출력

---
workspace:
  base: x
  path: y
pipeline:
- validate-merge-request:
    pull: true
- import-groups-check:
    pull: true
- static-check:
    pull: true
- build:
    image: golang:1.9.0
- publish:
    image: plugins/docker:1.13
- notify-youtrack:
    pull: true

답변3

사용 ed:

ed -s file >/dev/null <<ED_END
/validate-merge-request:/
.,+2m/pipeline:/
wq
ED_END

편집 스크립트는 ed먼저 문자열이 포함된 행을 검색합니다 validate-merge-request:. 그런 다음 이 행과 포함 행 뒤의 두 행을 이동합니다 pipeline:. 그러면 파일이 동일한 이름으로 저장되고 스크립트가 종료됩니다.

validate-merge-request:일치하는 줄에서 다음 빈 줄로 줄을 이동하려면 /^$/대신 in 을 사용하세요 +2.

스크립트가 적절하게 변경되므로 주의하세요. 새 파일에 쓰려면 다음을 사용하십시오.

ed -s file >/dev/null <<ED_END
/validate-merge-request:/
.,+2m/pipeline:/
w file-new
ED_END

그러면 수정된 문서가 작성됩니다 file-new.

관련 정보