使用awk将格式化文件转换为json(处理非空行)

时间:2016-04-30 12:07:15

标签: json awk gawk

这是我要转换为json的示例文件。

Name: Jack
Address: Fancy road and some special characters :"'$@|,
   City
   Country
ID: 1

特殊字符是双引号,单引号,$,@,管道。我以为我可以使用awk中的记录分隔符:

awk -F ":" '{RS="\n"}{print $1}'

然而,我得到的是:

Name:
Address
   City
   Country
ID

我尝试将记录分隔符更改为“^ [a-zA-Z0-9]”以尝试捕获不以空格开头的字符串,但不知何故这不起作用。另一种尝试是简单地逐行解析文件,并根据每行的内容格式化输出,但这很慢。

理想情况下,我会将文件转换为:

{
"Name": "Jack",
"Address": "Fancy road and some special characters :\"'$@|, City, Country",
"ID": "1"
}

1 个答案:

答案 0 :(得分:2)

idk为什么你的问题在你的例子中没有空行而非GNU awk为第3个arg匹配()和gensub()时讨论非空行:

$ cat tst.awk
BEGIN { printf "{" }

match($0,/^(\S[^:]+):\s*(.*)/,a) {
    prt()
    key = a[1]
    val = a[2]
    next
}

{ val = gensub(/,\s*$/,"",1,val) gensub(/^\s*/,", ",1) }

END { prt(); print "\n}" }

function prt() {
    if (key != "") {
        printf "%s\n\"%s\": \"%s\"", (++c>1?",":""), key, gensub(/"/,"\\\\&","g",val)
    }
}

$ awk -f tst.awk file
{
"Name": "Jack",
"Address": "Fancy road and some special characters :\"'$@|, City, Country",
"ID": "1"
}

对代码的一些额外评论:

match()

  

match函数在字符串string中搜索正则表达式regexp匹配的最长,最左边的子字符串。它返回子字符串开始处的字符位置或索引(1,如果它从字符串的开头开始)。

\S

  

匹配任何不是空格的字符。可以把它想象为'[^ [:space:]]'的简写。

\s

  

匹配任何空格字符。可以把它想象成'[[:space:]]'的简写。