jq: 将 "header:" "line1" "line2" 文本文件转换为 JSON 流 w/ 映射到字符串列表

jq: Convert "header:" "line1" "line2" text file into JSON stream w/ map to lists of strings

如何将这些文本字符串列表转换为 json

文本字符串:

start filelist:
/download/2017/download_2017.sh
/download/2017/log_download_2017.json
/download/2017/log_download_2017.txt
start wget:
2017-05-15 20:42:00 URL:http://web.site.com/downloads/2017/file_1.zip [1024/1024] -> "file_1.zip" [1]
2017-05-15 20:43:21 URL:http://web.site.com/downloads/2017/file_2.zip [2048/2048] -> "file_2.zip" [1]

JSON 输出:

{
"start filelist": [
    "download_2017.sh",
    "log_download_2017.txt",
    "log_download_2017.json",
  ],
}
{
"start wget": [
    "2017-05-15 20:43:01 URL:http://web.site.com/downloads/2017/file_1.zip [1024/1024] -> "file_1.zip" [1]",
    "2017-05-15 20:43:21 URL:http://web.site.com/downloads/2017/file_2.zip [2048/2048] -> "file_2.zip" [1]",
  ],
}

欣赏任何选项和方法

这是一个仅限 jq 的解决方案,它根据您的示例生成有效的 JSON:

foreach (inputs,null) as $line ({};
   if $line == null then .emit = {(.key): .value}
   elif $line[-1:] == ":"
   then (if .key then {emit: {(.key): .value}} else null end)
        + { key : $line[0:-1] }
   else {key, value: (.value + [$line])}
   end;
   .emit // empty )

调用:

jq -n -R -f program.jq input.txt

请特别注意 -n 选项。

注意事项

如果输入不是以"key"行开头,那么上面的jq程序就会报错终止。如果需要更多的容错能力,那么可能会对以下变体感兴趣:

foreach (inputs,null) as $line ({};
   if $line == null then .emit = {(.key|tostring): .value}
   elif $line[-1:] == ":"
   then (if .key then {emit: {(.key): .value}} else null end)
        + { key : $line[0:-1] }
   else {key, value: (.value + [$line])}
   end;
   .emit // empty )