如何在bash中有效地基于公共文本字符串提取并合并文件的各个部分?

时间:2019-03-08 01:35:18

标签: bash shell text

假设我有两个类似的文件:

a.yaml

data:
- name: a1
  args: ["cmd", "something"]
  config:
  - name: some
    val: thing

- name: a2
  args: ["cmd2", "else"]

[...other array values...]

tags: ["something-in-a"]
values: ["else-in-a"]

substitutions:
  key1: a-value
  key2: a-value
  key3: a-value

b.yaml

data:
- name: b1
  args: ["cmd", "something"]
  config:
  - name: some
    val: thing

- name: b2
  args: ["cmd2", "else"]

[...other array values...]

tags: ["something-in-b"]
values: ["else-in-b"]

substitutions:
  key1: b-value
  key2: b-value
  key3: b-value

我的目标是合并文件a和b的各个部分,以使我拥有一个新文件,该文件由substitutions:的{​​{1}}之前的文件内容和{ {1}}

因此,在这种情况下,我想要的输出将是这样的:

c.yaml

b.yaml

两个文件内容中substitutions:之前和之后的部分长度可能不同。

当前,我的方法如下:

a.yaml

但是我想知道是否存在一种替代或更好的方法,可以基于bash中的通用文本字符串来组合不同文件的各个部分?

2 个答案:

答案 0 :(得分:2)

使用awk,您只需要根据字符串标记流:

awk '$1 == "substitutions:"{skip = FNR==NR ? 1:0}!skip' b.yaml a.yaml

说明:

  • FNR==NR:如果为true,则处理第一个文件b.yaml中的行,否则处理第二个文件a.yaml
  • !skip:如果为TRUE,则打印该行,否则跳过该行。

答案 1 :(得分:0)

{
    head -B9999 'substitutions:' a.yaml |  head -n -1
    head -A9999 'substitutions:' b.yaml
} > c.yaml

一个班轮:

{ head -B9999 'substitutions:' a.yaml |  head -n -1; head -A9999 'substitutions:' b.yaml; } > c.yaml

-A9999-B9999有点脏,这是sed的解决方案:

{
      sed '/substitutions:/,$d' a.yaml
      echo substitutions:
      sed '1,/substitutions:/d' b.yaml
} > c.yaml