Ключ преобразования: значение в файл CSV - PullRequest
0 голосов
/ 28 октября 2019

Я нашел следующий bash-скрипт для преобразования файла с ключом: информация о значении в CSV-файл:

awk -F ":" -v OFS="," '
BEGIN { print "category","recommenderSubtype", "resource", "matchesPattern", "resource", "value" }
function printline() {
print data["category"], data["recommenderSubtype"], data["resource"], data["matchesPattern"], data["resource"], data["value"]
}
{data[$1] = $2}
NF == 0 {printline(); delete data}
END {printline()}
' file.yaml

Но после выполнения он преобразует только первую группу данных (только первые 6 строк)данных), как это

category,recommenderSubtype,resource,matchesPattern,resource,value
COST,CHANGE_MACHINE_TYPE,instance-1,f1-micro,instance-1,g1-small

Мой оригинальный файл выглядит так (с 1000 строк и более):

category:COST
recommenderSubtype:CHANGE_MACHINE_TYPE
resource:portal-1
matchesPattern:f1-micro
resource:portal-1
value:g1-small
category:PERFORMANCE
recommenderSubtype:CHANGE_MACHINE_TYPE
resource:old-3
matchesPattern:n1-standard-4
resource:old-3
value:n1-highmem-2

Есть ли какая-либо команда, которую я пропускаю?

1 Ответ

0 голосов
/ 28 октября 2019

Проблема с оригинальным скриптом заключается в следующих строках:

NF == 0 {printline(); delete data}
END {printline()}

Первая строка означает: Вызовите printline (), если в текущей строке нет записей. Вторая строка означает вызов printline() после обработки всех данных.

Сложность формата входных данных заключается в том, что он не дает хорошего индикатора того, когда выводить следующую запись. Далее я просто изменил сценарий для вывода данных каждые шесть записей. В случае, если могут быть дублирующиеся ключи, критерием для вывода может быть «все заполненные поля» или что-то, что должно быть запрограммировано немного по-другому.

#!/bin/sh -e
awk -F ":" -v OFS="," '
BEGIN {
    records_in = 0
    print "category","recommenderSubtype", "resource", "matchesPattern", "resource", "value"
}
{
    data[$1] = $2
    records_in++
    if(records_in == 6) {
        records_in = 0;
        print data["category"], data["recommenderSubtype"], data["resource"], data["matchesPattern"], data["resource"], data["value"]
    }
}
' file.yaml

Другие рекомендации

  • Я только что удалил оператор delete, потому что не уверен, что он делает. Спецификация POSIX для awk определяет ее только для удаления элементов одного массива. В случае, если весь массив должен быть удален, рекомендуется выполнить цикл над элементами. Однако, если все поля присутствуют всегда, можно также полностью исключить его.
  • Добро пожаловать в SO (я тоже новичок здесь). В следующий раз, когда вы спросите, я бы рекомендовал пометить вопрос awk, а не bash, потому что AWK действительно является языком сценариев, используемым в этом вопросе, а bash отвечает только за вызов awk с подходящими параметрами:)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...