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:。次に、この行と埋め込み行の後の2行を移動します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

関連情報