这是我要转换为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"
}
答案 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:]]'的简写。