在bash中将行转换为json

jca*_*314 16 bash jq

我想将列表转换为JSON数组.我正在考虑jq这个,但示例主要是解析JSON(不创建它).知道正确的逃逸会很愉快.我的列表是单行元素,因此新行可能是最佳分隔符.

chb*_*own 25

我也试图将一堆行转换为JSON数组,并且处于停顿状态,直到我意识到这-s是我在jq表达式中一次处理多行的唯一方法,即使这意味着我有手动解析换行符.

jq -R -s -c 'split("\n")' < just_lines.txt
Run Code Online (Sandbox Code Playgroud)
  • -R 阅读原始输入
  • -s 将所有输入读作单个字符串
  • -c 不打印输出

十分简单.

编辑:我在jq≥1.4,这显然是split在引入内置的时候.

  • 我喜欢这个答案,除了对于具有尾随换行符(\n)的多行输出,`split`内置函数将在数组中产生一个额外的空字符串项:(无论如何要修复它? (4认同)
  • 考虑 `'split("\n") | map(select(length &gt; 0))'` 也可以删除空行。 (3认同)
  • 我目前的 hack 是将它重新封装到 `jq` 中以使用它的切片功能 ¯\_(ツ)_/¯ `echo $(jq -R -s -c 'split("\n")' &lt; urls.txt) | jq '.[:-1]'` (2认同)

nis*_*ama 8

您还可以使用jq -R .将每行格式化为JSON字符串,然后jq -s(--slurp)在将它们解析为JSON后为输入行创建数组:

$ printf %s\\n aa bb|jq -R .|jq -s .
[
  "aa",
  "bb"
]
Run Code Online (Sandbox Code Playgroud)

如果输入以换行结束,则chbrown的答案中的方法会向末尾添加一个空元素,但您可以使用printf %s "$(cat)"删除尾随换行符:

$ printf %s\\n aa bb|jq -R -s 'split("\n")'
[
  "aa",
  "bb",
  ""
]
$ printf %s\\n aa bb|printf %s "$(cat)"|jq -R -s 'split("\n")'
[
  "aa",
  "bb"
]
Run Code Online (Sandbox Code Playgroud)

如果输入行不包含ASCII控制字符(必须在有效JSON中的字符串中转义),您可以使用sed:

$ printf %s\\n aa bb|sed 's/["\]/\\&/g;s/.*/"&"/;1s/^/[/;$s/$/]/;$!s/$/,/'
["aa",
"bb"]
Run Code Online (Sandbox Code Playgroud)


Cor*_*eld 5

我在 jq 的手册页中找到了,并通过实验在我看来是一个更简单的答案。

$ cat test_file.txt | jq -Rsc '. / "\n" - [""]'
["aa","bb"]
Run Code Online (Sandbox Code Playgroud)

-R 表示读取而不尝试解析 json,-s 表示将所有输入作为一个字符串读取,而 -c 表示一行输出 - 不是必需的,但这正是我正在寻找的。

然后在我传递给 jq 的字符串中,“.” 说按原样接受输入。'/ \n' 表示在换行符上分割字符串(拆分它)。'- [""]' 表示从结果数组中删除任何空字符串(由末尾的额外换行符产生)。

它只是一行,没有任何复杂的构造,仅使用简单的内置 jq 功能。


Sri*_*bat 5

--raw-input,然后--slurp

只是以希望更快理解的形式总结其他人的话:

cat /etc/hosts  | jq  --raw-input .  | jq --slurp .
Run Code Online (Sandbox Code Playgroud)

将返回您:

[
  "fe00::0 ip6-localnet",
  "ff00::0 ip6-mcastprefix",
  "ff02::1 ip6-allnodes",
  "ff02::2 ip6-allrouters"
]
Run Code Online (Sandbox Code Playgroud)

说明

 --raw-input/-R:

       Don´t parse the input as JSON. Instead, each line of text is passed
       to  the  filter  as  a  string.  If combined with --slurp, then the
       entire input is passed to the filter as a single long string.

 --slurp/-s:

       Instead of running the filter for each JSON object  in  the  input,
       read  the entire input stream into a large array and run the filter
       just once.
Run Code Online (Sandbox Code Playgroud)


pea*_*eak 5

更新:如果你的 jq 有inputs你可以简单地写:

jq -nR [inputs] /etc/hosts 
Run Code Online (Sandbox Code Playgroud)

生成一个 JSON 字符串数组。这避免了必须阅读整个文本文件。