Unix конкатенировать вложенный / с отступом список значений? - PullRequest
0 голосов
/ 18 марта 2019

Я пытаюсь создать иерархический список из списка пар ключ-значение с отступом (2 пробела). изменено оригинальное содержание

РЕДАКТИРОВАТЬ: извинения.Я закончил тем, что вставил неправильный вывод.исходный файл yaml имеет этот формат.получение «описания» - моя вторичная цель:

schemas:
- name: exports
  tables:
  - name: sugar
    description: makes stuff sweet
    active_date: 2019-01-07 00:00:00
    columns:
    - name: color
      type: abcd
    - name: taste
      type: abcd
      description: xyz
      example: 21352352
    - name: structure
      type: abcd
      description: xyzasaa
      example: 10001
  - name: salt
    description: not that sweet.
      makes it salty.
    active_date: 2018-12-18 00:00:00
    columns:
    - name: strength
      type: abcdef
      description: easy to find
      example: 2018-03-03 12:30:00
    - name: color
      type: abcdeffa
      description: not sweet
      example: 21352352
    - name: quality
      type: abcd
      description: how much is needed
      example: 10001

Лучший желаемый результат будет ниже, где я пытаюсь сгенерировать CSV и сгладить yaml с каждой строкой, содержащей самый дочерний элемент со всеми родителями.значения:

sugar.color,abcd
sugar.taste,abcd,xyz
sugar.structure,abcd,xyzasaa
salt.strength,abcdef,"easy to find"
salt.color,abcdeffa,"not sweet"
salt.quality,abcd,"how much is needed"

, но я не знаю, насколько это возможно, поэтому ищу по крайней мере:

sugar.color
sugar.taste
sugar.structure
salt.strength
salt.color
salt.quality

Ответы [ 2 ]

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

Использование любого awk в любой оболочке на любом компьютере UNIX:

$ cat tst.awk
BEGIN { OFS = "," }

match($0,/^ +- /) { indent = RLENGTH }

$1 == "-" {
    prt()
    if (indent == 4) {
        key = $NF
        subKey = ""
    }
    else if (indent == 6) {
        subKey = $NF
    }
    next
}

subKey != "" {
    data = substr($0,indent+1)

    if ( data ~ /^[^[:space:]]/ ) {
        # new data
        tag = data
        sub(/:.*/,"",tag)
        sub(/^[^:]+: */,"",data)
        f[tag] = data
    }
    else {
        # continuation of previous data
        sub(/^[[:space:]]*/,"",data)
        f[tag] = f[tag] " " data
    }
}

END { prt() }

function prt() {
    if ( "type" in f ) {
        print key "." subKey, f["type"], "\"" f["description"] "\""
    }
    delete f
}

$ awk -f tst.awk file
sugar.color,abcd,""
sugar.taste,abcd,"xyz"
sugar.structure,abcd,"xyzasaa"
salt.strength,abcdef,"easy to find"
salt.color,abcdeffa,"not sweet"
salt.quality,abcd,"how much is needed"

Если любой description является многострочным, вышеприведенное объединит его в одну строку.

1 голос
/ 18 марта 2019

Вот скрипт на Perl, который выдает желаемый результат.

#!/usr/bin/perl
use warnings;
use strict;
use feature qw/postderef/;
no warnings qw/experimental::postderef/; # Suppress warning on 5.20 and 5.22
use YAML::XS qw/LoadFile/;
use Text::CSV_XS;

my $yaml = LoadFile($ARGV[0]);
my $csv = Text::CSV_XS->new({quote_space => 1, eol => "\n"});

for my $schema ($yaml->{'schemas'}->@*) {
    for my $table ($schema->{'tables'}->@*) {
        for my $col ($table->{'columns'}->@*) {
            my @row = ("$table->{name}.$col->{name}", $col->{type});
            push @row, $col->{'description'} if exists $col->{'description'};
            $csv->print(\*STDOUT, \@row);
        }
    }
}

Пример:

$ perl example.pl test.yaml
sugar.color,abcd
sugar.taste,abcd,xyz
sugar.structure,abcd,xyzasaa
salt.strength,abcdef,"easy to find"
salt.color,abcdeffa,"not sweet"
salt.quality,abcd,"how much is needed"

Требуется пара нестандартных модулей: YAML :: XS (пакет Debian / Ubuntu libyaml-libyaml-perl) и Текст :: CSV_XS (Debian / Ubuntu libtext-csv-xs-perl)


YAML - это формат разметки структурированных данных, и попытка сделать что-то с ним по одной строке за раз с помощью регулярных выражений или тому подобного настраивает себя на неудачу; любой ввод, который отличается от того, что вы ожидаете, приведет к его сбою; и отсутствие контекста в более широкой картине и множество крайних случаев делают невозможным быть надежным. То же самое для попытки анализа таких вещей, как CSV, XML / HTML или JSON с регулярными выражениями.

Вам лучше использовать инструмент или библиотеку, которая понимает формат. Таким образом, приведенное выше использует синтаксический анализатор YAML для преобразования вашего файла в эквивалентную структуру данных perl, а затем проверяет это, распечатывая соответствующие значения. Он использует библиотеку CSV для форматирования вывода, чтобы избежать необходимости вручную обрабатывать поля кавычек с пробелами, как это делает желаемый вывод, и все другие крайние случаи, такие как кавычки в полях.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...