2014-10-09 109 views
4

我想将列表转换为JSON数组。我正在寻找jq,但这些例子主要是关于解析JSON(而不是创建它)。很高兴知道正确的转义会发生。我的列表是单行元素,因此新行可能是最好的分隔符。在bash中将行转换为json

+1

BTW,本 - 1不是我,但如果我不得不猜测为什么它在那里,那可能是“请为我做我的工作“这个问题(否则有用和值得,因此我的回答)问题发出。显示你的工作和你试图解决这个问题的问题可以避免这种情况。 – 2014-10-09 21:53:21

+0

谢谢,是的,我没有谷歌。我正在寻找一个小的一行,可能是我在'jq'手册页中错过的东西。感谢您的反馈,即投票是我的。 – jcalfee314 2014-10-09 23:42:08

回答

10

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

jq -R -s -c 'split("\n")' < just_lines.txt 
  • -R读取原始输入
  • -s读取所有输入一个字符串
  • -c不漂亮的打印输出

易peasy。

编辑:我在jq≥1.4,这显然是当split内置引入。

+0

看起来很简单..虽然我无法验证。我在ubuntu jq 1.3版上遇到错误'error:split is not defined' – jcalfee314 2015-01-18 16:18:00

+1

不幸的是,'jq'文档并没有说每个内置函数何时被引入,'jq --version'也不会告诉我什么版本我有,但它至少是1.4,用'brew install jq --HEAD'安装。好点,但我会编辑答案。 – chbrown 2015-01-18 20:15:19

+3

我喜欢这个答案,除了对于具有尾随换行符(\ n)的多行输出,'split'内置函数将在数组中产生额外的空字符串项目:(无论如何解决这个问题? – Devy 2016-10-21 15:46:11

3

您还可以使用jq -R .于每行格式化为JSON字符串,然后jq -s--slurp)以解析它们作为JSON之后创建用于将输入线的阵列:

$ printf %s\\n aa bb|jq -R .|jq -s . 
[ 
    "aa", 
    "bb" 
] 

的方法,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" 
] 

如果输入线不包含ASCII控制字符(其中有在有效的JSON字符串进行转义),你可以使用sed

$ printf %s\\n aa bb|sed 's/["\]/\\&/g;s/.*/"&"/;1s/^/[/;$s/$/]/;$!s/$/,/' 
["aa", 
"bb"] 
+0

当从jq到jq的管道输入时, '漂亮的打印是没有必要的:'jq -cR。| jq -s .' – ceving 2016-10-27 10:00:59

+1

而不是在一个单独的调用中sl inputs输入,只需将原始输入放入一个数组中''jq -Rn'[inputs]'input.json '。这些都是等价的:'jq -s'。'input.json'和'jq -n'[inputs]'input.json' – 2017-08-10 03:18:52

1

我在man page发现JQ并通过实验似乎什么对我来说是一个更简单的答案。

$ cat test_file.txt | jq -Rsc './"\n" - [""]' 
["aa","bb"] 

的-R是不分析JSON阅读,与-s说,读所有的输入作为一个字符串,和-c是一个行输出 - 没有必要的,但它是什么我在寻找。

然后在字符串我传递给jq,'。'说按原样进行输入。 '/ \ n'表示在换行符上划分字符串(将其拆分)。 ' - [“”]'表示从结果数组中删除任何空字符串(在最后一个额外的换行符导致)。

这是一条线,没有任何复杂的构造,只使用简单的内置jq功能。

1

只是总结一下别人的希望更快地了解表格说:

cat /etc/hosts | jq --raw-input . | jq --slurp . 

将返回:

[ 
    "fe00::0 ip6-localnet", 
    "ff00::0 ip6-mcastprefix", 
    "ff02::1 ip6-allnodes", 
    "ff02::2 ip6-allrouters" 
] 

说明

--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.