首页 > 解决方案 > 根据第一个的属性获取项目和后续项目

问题描述

我有一个无法更改的第三方工具生成的事件日志文件。因此,这个日志文件是一个巨大的 JSON 数组,其中赔率元素包含元数据,而对包含与元数据关联的正文消息。我希望能够根据元数据拆分文件,按主题将信息聚集在不同的文件中。

我正在 Windows 上处理这个项目,我正在使用批处理文件和 JQ 进行尝试。

基本上数组看起来像这样:

[
  { "type": "abc123"},
  {"name":"first component of type abc123"},
   { "type": "abc123"},
  {"name":"second component of type abc123"},
  { "type": "def124"},
  {"name":"first component of type def124"},
  { "type": "xyz999"},
  {"name":"first component of type xyz999"},
  { "type": "abc123"},
  {"name":"third component of type abc123"},
  { "type": "def124"},
  {"name":"second component of type def124"},
  { "type": "abc123"},
  {"name":"fifth component of type abc123"},
  { "type": "abc123"},
  {"name":"sixth component of type abc123"},
  { "type": "def124"},
  {"name":"third component of type def124"},
  { "type": "def124"},
  {"name":"fourth component of type def124"},
  { "type": "abc123"},
  {"name":"seventh component of type abc123"},
  { "type": "xyz999"},
  {"name":"second component of type xyz999"}
  ...
]

我知道我只有 3 种类型,所以我要归档的是为每种类型创建一个文件。就像是:

第一个文件

{
  "componentLog": {
       "type": "abc123",
       "information": [
          "first component of type abc123",
          "second component of type abc123",
          "third component of type abc123",
          ...
       ]
     }
}

第二个文件

{
  "componentLog": {
       "type": "def124",
       "information": [
          "first component of type def124",
          "second component of type def124",
          "third component of type def124",
          ...
       ]
     }
}

第三档

{
  "componentLog": {
       "type": "xyz999",
       "information": [
          "first component of type xyz999",
          "second component of type xyz999",
          "third component of type xyz999",
          ...
       ]
     }
}

我知道我可以将元数据与此分开

jq.exe ".[] | select(.type==\"product\")" file.json

然后我尝试计算index.But index 只返回包含 select 语句的第一个项目的索引......所以我不知道如何解决这个问题......

标签: jsonbatch-filejqdata-partitioning

解决方案


下面的 bash 脚本有点混乱,因为它假定所有文件(输入或输出)都不适合内存。

如果您还没有在您的计算环境中访问 bash、sed 和 awk,您可能需要考虑安装或类似的,或者您可以适当地调整脚本,例如使用gawk for WindowsRuby对于 Windows

原始问题中尚未嵌入的另一个主要假设是可以删除log-type*.tmp文件并为“type”的各种值覆盖 log-TYPE.json。

请务必设置input为适当的输入文件名。

# The input file name:
input=file.json

/bin/rm log-type*.tmp

# Use jq to produce a stream of .type and .name values 
# as per the jq FAQ
jq -cn --stream '
   fromstream(1|truncate_stream(inputs))
   | if .type then .type else .name end'  "$input" |
 awk '
      NR%2 {fn=$1; sub("^\"","",fn); sub("\"$","", fn); next;} 
      { print > "log-type." fn ".tmp"}
'

for f in log-type.*.tmp ; do
    echo formatting $f ...
    g=$(sed -e 's/log-type.//' -e 's/.tmp$//' <<< "$f")
    echo g="$g"
    awk -v type="\"$g\"" '
      BEGIN { print "{\"componentLog\": { \"type\": " type " ,";
      print "\"information\": ["; }
      NR==1 { print; next }
      {print ",", $0} 
      END {print "]}}"; }' "$f" > "log-$g.json"
done

推荐阅读