Печатать до и после каждой записи в awk - PullRequest
0 голосов
/ 09 июня 2019

Я пытаюсь преобразовать LDIF в JSON, используя awk.

Не могу понять, как печатать до и после каждой многострочной записи.Может печатать в НАЧАЛЕ и КОНЕЦ один раз или до и после каждой строки.Но никогда до и после каждой записи.

Фактический ввод LDIF в awk:

dn: CN=foo
objectClass: top

dn: CN=bar
objectClass: top

Для преобразования в JSON awk необходим вывод, который должен выглядеть следующим образом:

{
  "dn": "CN=foo",
  "objectClass": "top"
}
{
  "dn": "CN=bar",
  "objectClass": "top"
}

Скрипт 1 заключает в каждую строку записи фигурные скобки.

BEGIN {                                                                                                                                                        
        RS="\n\n#";
        FS=": ";
}
print "{"
{
        print "\""$1"\": \""$2"\",";
}
print "}"

Скрипт 2 переносит все записи в набор фигурных скобок:

BEGIN {                                                                                                                                                        
        RS="\n\n#";
        FS=": ";
        print "{"
}
{
        print "\""$1"\": \""$2"\",";
}
END{
        print "}"
}

Похоже только на awkимеет BEGIN, END и неявный цикл по записям (однострочный или многострочный).Я не могу понять, как напечатать что-нибудь до и после каждой многострочной записи.Это возможно в awk?Есть ли лучший способ конвертировать LDIF в JSON?

Как бы выглядел сценарий awk, а не одна строка, который конвертирует LDIF в JSON?

1 Ответ

0 голосов
/ 09 июня 2019

Вдохните, что вы думаете, что будет делать скрипт awk, но чтобы получить ожидаемый результат, который вы опубликовали, из введенного вами, все, что вам нужно, это:

$ awk '!/^[{}]/{print ( (NR-1)%2 ? "{" ORS $0 : $0 ORS "}" )}' file
{
record1 line1
record1 line2
}
{
record2 line1
record2 line2
}

Обновление: с учетом обновленной входной печати до / после записи еще проще:

$ awk -v RS= '{print "{" ORS $0 ORS "}"}' file
{
dn: CN=foo
objectClass: top
}
{
dn: CN=bar
objectClass: top
}

и получить результат, который вы показали в своем вопросе, будет:

$ cat tst.awk
BEGIN { RS=""; FS="\n" }
{
    print "{"
    for (i=1; i<=NF; i++) {
        tag = val = $i
        sub(/:.*/,"",tag)
        sub(/[^:]+:[[:space:]]*/,"",val)
        printf "  \"%s\": \"%s\"%s\n", tag, val, (i<NF ? "," : "")
    }
    print "}"
}

$ awk -f tst.awk file
{
  "dn": "CN=foo",
  "objectClass": "top"
}
{
  "dn": "CN=bar",
  "objectClass": "top"
}
...