在 linux 上过滤直播 json 流

Filtering Live json Stream on linux

我有来自我正在使用的虚拟雷达服务器的实时原始 json 流数据。

我使用 Netcat 获取数据并使用 jq 将其保存在我的 kali linux 上。使用以下命令。

nc 127.0.0.1 30006 | jq > A7.json

但我想从数据流中过滤特定内容。

我使用以下命令提取数据。

cat A7.json | jq '.acList[] | select(.Call | contains("QTR"))' - To fetch Selected airline

但后来我意识到上面的命令只能执行一次。换句话说,它不会刷新。因为数据每秒都在更新。我必须一遍又一遍地执行命令来提取导致生成重复数据的过滤器数据。

谁能帮我过滤实时数据而不用一遍又一遍地执行命令。

由于您没有使用 --stream 选项,我想您的文档是 常规 JSON 文档。

要每秒执行您的命令,您可以实现一个 sleeps 持续 1 秒的循环:

while true; do sleep 1; nc 127.0.0.1 30006 | jq '.acList[] | select(…)'; done

要让屏幕上的输出 也保存到文件中(就像您对 A7.json 做的那样),您可以添加对 [=15= 的调用]:

# saves the document as returned by `nc` but outputs result of `jq`
while true; do sleep 1; nc 127.0.0.1 30006 | tee A7.json | jq '.acList[] | …'; done

# saves the result of `jq` and outputs it
while true; do sleep 1; nc 127.0.0.1 30006 | jq '.acList[] | …' | tee A7.json; done

你能试试这个吗?

nc localhost 30006 | tee -a A7.json |
   while true; do
      stdbuf -o 0 jq 'try (.acList[] | select(.Call | contains("QTR")))' 2>/dev/null
   done

假设没有其他进程在争夺端口,我建议尝试:

nc -k -l localhost 30006 | jq --unbuffered ....

或者如果您想保留 netcat 命令输出的副本:

nc -k -l localhost 30006 | tee A7.json | jq --unbuffered ....

您可能想改用 tee -a A7.json

崩溃


为什么我做了我所做的?


  • 我有来自虚拟雷达服务器的实时原始 json 流数据,它在我的笔记本电脑上 运行 以及后台的 Kali Linux WSL。

  • 对于那些不知道虚拟雷达服务器的人来说,虚拟雷达服务器是一个 Modes-s 传输解码器,用于解码不同的 ADS-B 格式。此外,它以各种格式重新广播数据。其中之一是 Json 流。我想在 Kali Linux.

    上以 json 格式保存 select 飞机数据
  • 我之前使用以下命令保存数据


$ nc 127.0.0.1 30001 | jq > A7.json - To save the stream.

$ cat A7.json | jq '.acList[] | select(.Call | contains("QTR"))' - To fetch Selected airline

  • 但是在使用上面的之后我意识到了两件事。一个是我正在存储不需要的数据,这些数据正在消耗我的存储空间。第二,当我使用第二个命令时,它只遍历 json 文件一次,并生成当时保存的数据,并且单独保存。这给我带来了问题,因为我必须一遍又一遍地执行命令来提取导致我生成重复数据的过滤器数据。

命令对我有效


以下命令完美解决了我的问题。

$ nc localhost 30001 | sudo jq --unbuffered '.acList[] | select (.Icao | contains("800CB8"))' > A7.json

下面的也给我带来了一些麻烦,我在下面解释清楚。


错误 X 解释


此错误是由于 json 对象中缺少字段名称和键造成的。

$ nc localhost 30001 | sudo jq --unbuffered '.acList[] | select (.Call | contains("IAD"))' > A7.json

#OUTPUT

jq: error (at <stdin>:0): null (null) and string ("IAD") cannot have their containment checked

如果您看到以下 JSON 数据,您将看到导致上述错误消息的缺失字段名称和键。

{
  "Icao": "800CB8",
  "Alt": 3950,
  "GAlt": 3794,
  "InHg": 29.7637787,
  "AltT": 0,
  "Call": "IAD766",
  "Lat": 17.608658,
  "Long": 83.239166,
  "Mlat": false,
  "Tisb": false,
  "Spd": 209,
  "Trak": 88.9,
  "TrkH": false,
  "Sqk": "",
  "Vsi": -1280,
  "VsiT": 0,
  "SpdTyp": 0,
  "CallSus": false,
  "Trt": 2
}
{
  "Icao": "800CB8",
  "Alt": 3950,
  "GAlt": 3794,
  "AltT": 0,
  "Lat": 17.608658,
  "Long": 83.239166,
  "Mlat": false,
  "Spd": 209,
  "Trak": 88.9,
  "Vsi": -1280
}
{
  "Icao": "800CB8",
  "Alt": 3800,
  "GAlt": 3644,
  "AltT": 0,
  "Lat": 17.608795,
  "Long": 83.246155,
  "Mlat": false,
  "Spd": 209,
  "Trak": 89.2,
  "Vsi": -1216
}

对我不起作用的命令。


命令#1

当我将 jq 与 --stream 与过滤器一起使用时,它产生了以下输出。 --Stream 输出过滤器工作正常。

$ nc localhost 30001 | sudo jq --stream '.acList[] | select (.Icao | contains("800"))' > A7.json

#OUTPUT

jq: error (at <stdin>:0): Cannot index array with string "acList"
jq: error (at <stdin>:0): Cannot index array with string "acList"
jq: error (at <stdin>:0): Cannot index array with string "acList"
jq: error (at <stdin>:0): Cannot index array with string "acList"
jq: error (at <stdin>:0): Cannot index array with string "acList"
jq: error (at <stdin>:0): Cannot index array with string "acList"
命令#2

出于某种原因 -k -l 无法收听数据。但另一个命令运行良好。我认为它不起作用,因为 wsl 之外的现有端口。

$ nc -k -l localhost 30001

$ nc localhost 30001

Thank you to everyone who helped me to solve my issue. I'm very grateful to you guys