sed: move as linhas correspondentes para depois de um padrão?

0

Eu tenho um arquivo de configuração .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

O que eu quero é mover o validate-merge-request para o primeiro passo:

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

Eu sei que podemos usar algo assim para extrair a etapa validate-merge-request :

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

Como posso mover isso para depois do pipeline: ?

    
por quanta 28.06.2018 / 16:16

3 respostas

1

POSIXLY:

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

Note que todas as linhas após pipeline: e não em validate-merge-request bloco serão mantidas na memória.

    
por 28.06.2018 / 16:31
1

Os mapeamentos são inerentemente não-ordenados. Se você quiser que os dados do pipeline sejam ordenados, você precisa de uma sequência:

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

Obviamente, isso afetará como você está processando atualmente o arquivo YAML.

Se você fizer essa alteração, poderá fazer algo assim:

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

quais saídas

---
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
    
por 28.06.2018 / 16:45
1

Usando ed :

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

O script de edição ed pesquisará primeiro a linha que contém a string validate-merge-request: . Em seguida, ele move essa linha e as duas linhas imediatamente a seguir à linha contendo pipeline: . O arquivo é salvo com o mesmo nome e o script sai.

Para mover as linhas da linha correspondente validate-merge-request: para a próxima linha em branco, use /^$/ no lugar de +2 .

O script faz a mudança no lugar, então tenha cuidado. Para escrever para um novo arquivo, use

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

Isso gravaria o documento modificado em file-new .

    
por 28.06.2018 / 17:23

Tags