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.

相关内容