使用命令行工具排序JSON/JavaScript元组



我在一个文件中有一个JavaScript元组列表,每行一个,如下:

{ x : 12, y : -1.0, as : [ 2, 0, 0 ], str : "xxx", d : 0.041 },
{ x : 27, y : 11.4, as : [ 1, 1, 7 ], str : "yyy", d : 0.235 },
{ x : -4, y :  2.0, as : [ 7, 8, 3 ], str : "zzz", d : 0.002 },
{ x : 44, y :  5.4, as : [ 9, 4, 6 ], str : "kkk", d : 0.176 },

我想根据给定字段的值(在我的示例中是d字段)对它们进行排序,最好使用命令行工具(这是包含许多步骤的过程的一部分)。

如果它有任何区别,我们可以假设所有行都有完全相同的长度(我可以知道d值的开始和结束索引),尽管我更喜欢不依赖于此的解决方案

这个问题已经过去一段时间了。

现在,基于工具的方法是使用jq: 之类的东西。
cat data.json | jq 'sort_by(.d)' >> data_sorted.json

更多信息请查看网站:

jq就像JSON数据的sed——你可以用它来切片、过滤、映射和转换结构化数据,就像sed、awk、grep和其他工具让你处理文本一样容易。

https://stedolan.github.io/金桥/

如果出于某种原因你不喜欢jq,还有很多选择

  • jsonpipe
  • json
  • json:选择
  • json-command
  • jsawk
  • jshon
  • json2

如果您能保证所有字段的大小相同,您可以使用排序命令。例如,这将按列x值进行数字排序。

cat <your file.dat> | sort -n -k 5,7

数据你在这里作为例子不是有效的JSON,但javascript语法。一种方法是包装文件,使其成为有效的javascript程序并在node。js命令行

中运行
var l = [
    { x : 12, y : -1.0, as : [ 2, 0, 0 ], str : "xxx", d : 0.041 },
    { x : 27, y : 11.4, as : [ 1, 1, 7 ], str : "yyy", d : 0.235 },
    ...
]
l.sort(function(o1, o2) { return o1.d < o2.d ? -1 : 1 });
console.log(l);

这是一个hack,但是如果每个JSON记录是一行,并且您知道d的值在每行上相同数量的空格分隔令牌之后开始,那么您可以使用

sort -g -k 20 < in > out

,它将基于第20个空格分隔的组件对行进行数字比较。为了增加舒适性,您可以使用-t(可能是:)指定不同的分隔符,并根据需要将参数调整为-k,但这仍然是一个hack:)

sort通常是精心优化的速度,所以你不太可能找到更快的。

如果输入数据中每行有一个JSON(如问题所示),那么@Ashley Coolman的解决方案不起作用,如下所示:

使用jq按值排序JSON可以很容易地通过使用sort_by()函数。使用sort_by()函数的主要技巧JSON输入必须是一个数组。有不同的方法要在jq中做到这一点(如果您的数据还不是这样的话),包括使用-s或——slurp选项。——slurp选项将读取所有JSON输入到JSON数组。从这一点的数据可以排序价值。您可以使用。[]语法返回数组的所有元素。

这意味着问题数据的正确解决方案如下:

cat data.json | jq -s -c 'sort_by(.d) | .[]' >> data_sorted.json

您也可以这样使用GNU的sort:

$ sort -t: -k6 -n test.csv
{ x : -4, y :  2.0, as : [ 7, 8, 3 ], str : "zzz", d : 0.002 },
{ x : 12, y : -1.0, as : [ 2, 0, 0 ], str : "xxx", d : 0.041 },
{ x : 44, y :  5.4, as : [ 9, 4, 6 ], str : "kkk", d : 0.176 },
{ x : 27, y : 11.4, as : [ 1, 1, 7 ], str : "yyy", d : 0.235 },

-k标志获取列索引。-t:是使用:作为分隔符,-n是数字。

当然,如果您在d之后添加另一个字段,则此解决方案将不起作用。如果是这种情况,您可以更改-k的值以只考虑特定字符,例如-k6.2,6.6,但这将假设.后面的位数恰好是3。

最新更新