簡體   English   中英

提取一列的一部分並使用awk保存到另一文件中

[英]Extract part of one column and save into another file using awk

我需要從csv文件中提取字段。 有兩列billing_infokey_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中提到的格式提取數據。 請幫忙

做一些假設:

  • 輸入的第一行列出了列名
  • 大括號分隔的元素包含任意數量的逗號分隔鍵/值對
  • 鍵值對可以按任意順序出現
  • 值由單引號分隔
  • 逗號不能出現在鍵或值內
  • 單引號不會出現在其他任何地方
<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部分處理標題
    • 即使沒有輸入,我們也會輸出標題
  • for循環遍歷所有字段(最后一個字段除外)
  • ($i ~ /id_encrypted/)查找包含關鍵字的任何內容
  • split用單引號( /\\047/ )拆分該字段
  • print輸出找到的值,最后一個字段

這是使用awk的快速而優雅的解決方案:

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

附帶說明:

-F ":"使awk字段分隔符:

split($3,arr1,",")將第三個字段除以,分成具有2個元素的數組。

split($6,arr2,",")由分割第六字段,為具有2個元素的數組。

然后打印出arr1的第一個元素和arr2的第二個元素。

我建議您將整個輸入轉換為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作為split()的第四個參數。 取消注釋print trace行,以查看每個步驟在做什么。 如果刪除或替換每個字段中的逗號(尤其是地址),則無需在每個輸出字段周圍添加雙引號。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM