【问题标题】:shell script: convert raw output (from dict lines into csv) [closed]shell脚本:转换原始输出(从dict行到csv)[关闭]
【发布时间】:2021-02-03 13:11:18
【问题描述】:

谁能帮我将以下原始输出转换为csvkey value pair

我尝试过awksed 方法,但问题是... data{} 包含 2 个键值对,有时它只有一个键值对,如第 3 行所示。 (第 3 行缺少 myID)

"data":{"myID":"111" "Country":"United Kingdom"
"data":{"myID":"222" "Country":"Germany"
"data":{"Country":"United Kingdom" "data":{"myID":"444"
"Country":"United Kingdom" "data":{"myID":"555"
"Country":"United Kingdom" "data":{"Country":"United Kingdom"

试图低于输出。

111,United Kingdom
222,Germany
,United Kingdom
444,United Kingdom
555,United Kingdom
,United Kingdom

请帮忙..提前谢谢。

【问题讨论】:

  • 这看起来像损坏的 json。你有原始有效的json数据吗?
  • @Shawn - 这是从服务器接收的 API 输出,我在我的 shell 脚本中使用 grep 过滤了不需要的行。这是我设法得到的输出。
  • 您应该使用像 jq 这样的 json 感知工具,而不是像 grep 或 sed 这样的工具。
  • 第三行输出,United Kingdom 来自哪里?请edit您的问题进行解释或解决。

标签: linux shell awk sed


【解决方案1】:

只要您的数据中有标签-值对,最好构建一个数组,将这些标签(也称为名称或键)映射到它们的值,然后您可以按名称打印它们。如果您将来发现自己的数据具有更多标签值对,只需将标签名称添加到第一个 arg 到 split() 的字符串中,脚本的其余部分将按原样工作:

$ cat tst.awk
BEGIN {
    numTags = split("myID Country",tagList)
    for (i in tagList) {
        tags[tagList[i]]
    }
    FS = "\""
    OFS = ","
}
{
    delete tag2val
    for (i=2; i<NF; i++) {
        if ( $i in tags ) {
            tag2val[$i] = $(i+2)
        }
    }
    for (tagNr=1; tagNr<=numTags; tagNr++) {
        tag = tagList[tagNr]
        val = tag2val[tag]
        printf "%s%s", val, (tagNr<numTags ? OFS : ORS)
    }
}

$ awk -f tst.awk file
111,United Kingdom
222,Germany
444,United Kingdom
555,United Kingdom
,United Kingdom

【讨论】:

    【解决方案2】:

    这可能对你有用(GNU sed):

    sed 'N;s/\n"Country":/,/;s/ "data":{/\n/;s/"data":{\|"myID"://g;s/ *"Country":/,/g;s/"//g;P;D' file
    

    根据提供的数据,此 sed 解决方案提供了规定的格式,但我认为可能存在未考虑的边缘情况。

    【讨论】:

    • 非常感谢@potong,您节省了我的时间,效果很好。
    猜你喜欢
    • 2017-07-04
    • 1970-01-01
    • 2020-06-13
    • 1970-01-01
    • 1970-01-01
    • 2020-05-13
    • 2011-08-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多