Извлеките часть одного столбца и сохраните в другой файл, используя awk - PullRequest
0 голосов
/ 26 марта 2019

У меня есть требование извлечь поля из CSV-файла. Есть два столбца billing_info и key_id. billing_info - это объект, имеющий несколько элементов данных в фигурных скобках. Мне нужно извлечь billing_info.id_encrypted, key_id в другой файл.

input.csv

  billing_info,key_id
    {id: '1B82', id_encrypted: '1Q4AW5bwyU', address: 'san jose', phone: '13423', country: 'v73jyqgE='},bf6-96f751

output.csv

 billing_info.id_encrypted,key_id
 1Q4AW5bwyU,bf6-96f751

Могу ли я узнать, как использовать команду awk для извлечения данных в формате, указанном в output.csv. Пожалуйста, помогите

Ответы [ 3 ]

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

С некоторыми предположениями:

  • в первой строке ввода перечислены имена столбцов
  • элемент с разделителями в скобках содержит произвольное количество пар ключ-значение, разделенных запятыми
  • пары ключ-значение могут появляться в произвольном порядке.
  • значения разделяются одинарными кавычками
  • запятые не могут появляться внутри ключей или значений
  • одинарные кавычки делаютбольше нигде не появляется
<csvfile | awk -F, '
    BEGIN {
        getline
        print "billing_info.id_encrypted,key_id"
    }
    {
        for (i=1; i<NF; i++)
            if ($i ~ /id_encrypted/)
                split($i, e, /\047/)
        print e[2] "," $NF
    }
'

Примечания:

  • -F, разбивает строки ввода на разделенные запятыми поля
  • BEGIN раздел обрабатываетheader
    • выводим заголовок, даже если нет ввода
  • for цикл проходит через все поля (кроме последнего)
  • ($i ~ /id_encrypted/) ищет любое, содержащее ключевое слово
  • split, разбивает это поле на одинарные кавычки (/\047/)
  • print выводит найденное значение и последнее поле
0 голосов
/ 26 марта 2019

Я рекомендую вам просто преобразовать весь ввод в CSV, и ТОГДА вы можете тривиально извлечь из него все поля, которые вам нравятся, используя awk или Excel или любой другой инструмент, например:

$ cat tst.awk
BEGIN { FS=OFS="," }
FNR==1 {
    split($0,hdr)
    next
}
{
    fld[1] = fld[2] = $0
    sub(/,[^,]*$/,"",fld[1])
    gsub(/^{|}$/,"",fld[1])
    sub(/.*,/,"",fld[2])
    # print "trace: " hdr[1] "=<" fld[1] ">" | "cat>&2"
    # print "trace: " hdr[2] "=<" fld[2] ">" | "cat>&2"

    numTags = split(fld[1],tags,/'[^']*'/,vals)
    delete tags[numTags--]
    for (tagNr=1; tagNr<=numTags; tagNr++) {
        gsub(/^, *|: *$/,"",tags[tagNr])
        gsub(/^'|'$/,"",vals[tagNr])
        # print "trace:    " tagNr ": <" tags[tagNr] "=" vals[tagNr] ">" | "cat>&2"
    }
}
FNR == 2 {
    for (tagNr=1; tagNr<=numTags; tagNr++) {
        printf "%s.%s%s", hdr[1], tags[tagNr], OFS
    }
    print hdr[2]
}
{
    for (tagNr=1; tagNr<=numTags; tagNr++) {
        printf "\"%s\"%s", vals[tagNr], OFS
    }
    printf "\"%s\"%s", fld[2], ORS
}

.

$ awk -f tst.awk file
billing_info.id,billing_info.id_encrypted,billing_info.address,billing_info.phone,billing_info.country,key_id
"1B82","1Q4AW5bwyU","san jose","13423","v73jyqgE=","bf6-96f751"

Выше используется GNU awk для 4-го аргумента до split().Раскомментируйте строки print trace, чтобы увидеть, что делает каждый шаг, если хотите.Вам не нужно добавлять двойные кавычки вокруг каждого поля вывода, если вы удаляете или заменяете запятые в каждом поле (особенно адрес).

0 голосов
/ 26 марта 2019

Вот быстрое и элегантное решение с использованием awk:

awk -F ":" '{split($3,arr1,",");split($6,arr2,",");print arr1[1] "," arr2[2]}' input.csv > output.csv

С объяснением:

-F ":" сделать разделитель полей awk :

split($3,arr1,",") разделить 3-е поле на , на массив, содержащий 2 элемента.

split($6,arr2,",") разделить 6-е поле на , на массив, содержащий 2 элемента.

Затем распечатайте первый элемент в arr1, а второй элемент в arr2.

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