简体   繁体   中英

awk how to add new line after each 2wo pattern match

I have a yml file that is automatically generated depending on the received parameters in GitLab, it can contain many triggers (structure will be the same overall file), jobs. Here is an example of his possible data:

name-1-${VAR1}-${VAR2}:
  stage: trigger-1
  trigger:
    project: test/test1
    branch: master
    strategy: depend
  rules:
    - if: '$CI_PIPELINE_SOURCE == "pipeline"'

release-build-name_1:
  extends: 
    - .build-name_1
    - .test-name_1
  image: name
  variables:
    NAME_1: "build-name_1"
    ... # mean n+1 key: values, or another structure
  artifacts:
    expire_in: 1 week
    paths:
      - ${CI_PROJECT_DIR}/file_1.log
      ...
  rules:
    - if: $STAGE == "TEST1"
    - if: $STAGE == "TEST2"
      when: manual

name-2-${VAR1}-${VAR2}:
  stage: trigger-2
  rules:
    - if: '$CI_PIPELINE_SOURCE == "pipeline"'
    - if: $STAGE == "TEST1"
  trigger:
    project: test/test2
    branch: dev
    strategy: depend

name-1-${VAR3}-${VAR4}:
...

What I need:

  1. for each trigger with a name: "^name-1-*";
  2. find in it block: "rules:";
  3. add the additional line: "- if: $VALUE" in that block.

I don't understand how to add a check for blank lines between patterns.

Pseudo code of what I (think) need with awk:

n=0
  if   /^name-1-*/      { ++n }
  elif /^\s*$/          { n=0 }
  elif n== 1 and /  rules:/   { print "    - if: $VALUE" }

For structured data files such as YAML you should use an appropriate data processor, rather than a plain text editor. For instance, there is kislyuk/yq or mikefarah/yq for processing YAML.

With both of them you could just add such an array item using:

yq '.[keys | .[] | select(test("^name-1-"))].rules += [{"if": "$VALUE"}]' file.yaml
  • You may want to add the -i flag to modify the file in place
  • With the kislyuk/yq implementation you also may want to add the -y flag to output YAML again

Considering the updated sample input and the clarifying comment , if you want to add the new rule item only to those .rules arrays (of matching objects) that already existed previously, provide another criterion using has :

(
  .[keys | .[] | select(test("^name-1-"))]
  | select(has("rules"))
)
.rules += [{"if": "$VALUE"}]

(This could be further simplified towards the actual implementation of yq you are using. This more verbose version is geared to work for both implementations.)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM