是否可以在jq中的流上使用唯一运算符

时间:2019-06-04 15:11:57

标签: json command-line jq

以下代码

for i in {1..10}; do 
    echo '{"key":'$(($RANDOM % 3))'}'
    sleep 1 
done | jq -n '[inputs]|unique'

将打印(如果它们都已出现):

[
  {
    "key": 0
  },
  {
    "key": 1
  },
  {
    "key": 2
  }
]

问题是您需要等待10秒钟才能看到结果(10 * sleep 1)。是否有一个流版本,一旦出现新元素,它将刷新到stdout?

1 个答案:

答案 0 :(得分:1)

这是{unique”的stream-oriented定义:

def unique(stream):
  foreach stream as $s ({};
     ($s|type) as $t
     | ($s|tostring) as $y
     | if .[$t][$y] then .emit = false
       else .emit = true | (.item = $s) | (.[$t][$y] = true)
       end;
     if .emit then .item else empty end );

您可以将其与-n命令行选项一起使用,如下所示:

unique(inputs)

编程说明

上面面向流的“ unique”版本不需要某种排序,因此从某种意义上说,它比内置版本更省时。

所需空间在不同项目的数量上是线性的。如果已知流中的项目已排序(或排列为使所有相等的项目都相邻),则下面定义的uniq可能很有趣。

uniq / 1

jq Cookbook给出了uniq的定义,其行为更类似于Linux uniq

def uniq(s):
  foreach s as $x (null;
    if . == null or .emitted != $x then {emit: true, emitted: $x}
    else .emit = false
    end;
    if .emit then $x else empty end);