Как эффективно извлечь и объединить части файлов на основе общей текстовой строки в bash? - PullRequest
0 голосов
/ 08 марта 2019

Предположим, у меня есть два похожих файла:

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: с b.yaml и содержимого, включающего и после substitutions: с a.yaml

Таким образом, в этом случае мой желаемый вывод будет выглядеть так:

c.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: a-value
  key2: a-value
  key3: a-value

Части до и после substitutions: в обоих файлах содержимогоможет иметь разную длину.

В настоящее время мой метод выглядит следующим образом:

head -q -n `awk '/substitution/ {print FNR-1}' b.yaml` b.yaml >! c.yaml ; \
tail -q -n `awk '/substitution/ {ROWNUM=FNR} END {print NR-ROWNUM+1}' a.yaml` a.yaml >> c.yaml; \
rm a.yaml b.yaml; mv c.yaml a.yaml; # optional newfile renaming to original

Но мне интересно, есть ли альтернативный или лучший способ объединения частей разных файлов на основе общей текстовой строкив баш?

Ответы [ 2 ]

2 голосов
/ 08 марта 2019

Используйте awk, вам просто нужно пометить поток на основе строки:

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

Объяснение:

  • FNR==NR:если true, обрабатывать строки в первом файле b.yaml, в противном случае во втором файле a.yaml
  • !skip: если TRUE, вывести строку, в противном случае пропустить строку.
0 голосов
/ 08 марта 2019
{
    head -B9999 'substitutions:' a.yaml |  head -n -1
    head -A9999 'substitutions:' b.yaml
} > c.yaml

A oneliner:

{ 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...