【问题标题】:jq filter and select multiple conditions and columnsjq过滤并选择多个条件和列
【发布时间】:2021-12-19 01:58:09
【问题描述】:

我想将 Hadoop Yarn 作业历史文件解析为 csv/sql 格式以便轻松查询。

我从 .jhist 文件中提取了 AVRO 模式,使用 avro-tools-*.jar 将 avro 数据文件转换为 JSON 流,使用 jq 将流组合成单个 json,现在我需要提取某些字段来自某些单独的 jsons

[
  {
    "type": "AM_STARTED",
    "event": {
      "AMStarted": {
        "startTime": 1636039435822,
        "nodeManagerPort": 8041
      }
    }
  },
  {
    "type": "TASK_STARTED",
    "event": {
      "TaskStarted": {
        "taskid": "task_1351",
        "jobStatus": "Started"
      }
    }
  },
  {
    "type": "JOB_INITED",
    "event": {
      "JobInited": {
        "launchTime": 1636039438569,
        "totalMaps": 356,
        "totalReduces": 100
      }
    }
  },
  {
    "type": "JOB_FINISHED",
    "event": {
      "JobFinished": {
        "jobid": "job_1636039105678_0061",
        "finishTime": 1636043211181,
        "totalCounters": {
          "name": "TOTAL_COUNTERS",
          "groups": [
            {
              "name": "org.apache.hadoop.mapreduce.FileSystemCounter",
              "displayName": "File System Counters",
              "counts": [
                {
                  "name": "FILE_BYTES_READ",
                  "displayName": "FILE: Number of bytes read",
                  "value": 1156766568459
                },
                {
                  "name": "FILE_BYTES_WRITTEN",
                  "displayName": "FILE: Number of bytes written",
                  "value": 1720873364662
                },
                {
                  "name": "RANDOM_BYTES",
                  "displayName": "RANDOM: Bytes",
                  "value": 1720873311162
                }
                ]
            }
            ]
        }
      }
    }
  }
]

从类型 AM_STARTED 'json/index/row',我想要 event.AMStarted.startTime
忽略 TASK_STARTED - 我不想要任何类型中有“TASK”的东西
从 JOB_INITED,我想要所有字段
从 JOB_FINISHED,我想要完成时间,以及 FILE_BYTES_READ 和 FILE_BYTES_WRITTEN 的值

我希望所有这些都用逗号分隔(也许是“引用”),所以我可以将它们加载到 csv 中,然后再加载到 sql 表中。

预期输出:

1636039435822、1636039438569、356、100、1636043211181、1156766568459、1720873364662

this 的语法是什么?

【问题讨论】:

    标签: jq hadoop-yarn


    【解决方案1】:

    我会使用以下内容:

    jq -r 'map(.event | (.AMStarted.startTime // .JobQueueChange.jobQueueName // .JobInited[])) | @csv'
    

    map 将映射应用于输入数组的每个元素;我们访问他们的事件,然后尝试访问.AMStarted.startTime.JobQueueChange.jobQueueName.JobInited,我们将其拆分为组件。 @csv 过滤器以您预期的格式输出结果数组。

    请注意,这忽略了对象.type 上所需的过滤器,我认为这是可以的,因为.event 持有的对象同样具体。

    你可以try it here

    【讨论】:

    • 谢谢。事实证明我确实需要对 .type 进行过滤,因为我需要忽略数百种 TASK_STARTED 类型。如果没有,我最终会在我的 csv 中有几个 ,,,,,,,, 被忽略的事件。有没有一种优雅的方式来过滤地图,或者下面的“选择”答案是要走的路?
    • 抱歉,我认为不符合三个条件之一的对象不会出现在输出中。我无法立即处理它,但我会尽快修复我的答案,同时您是否可以编辑您的示例输入以添加应忽略的对象示例?
    • 也出现了错误(无法迭代空值,因为 JobInited[] 的余数)。查看更新的here
    • @d-_-b 是 this 你在找什么?
    • 我们可以指定 .type 不包含 'TASK' 吗?另外,我需要一些也被过滤的嵌套元素。不确定我是否必须指定整个路径,或者有办法对具有相同路径的元素进行分组和选择。更新问题
    【解决方案2】:

    这是原始问题的答案:

    从类型 AM_STARTED 'json/index/row',我想要 event.AMStarted.startTime
    从类型 JOB_QUEUE_CHANGED,我想要 event.JobQueueChange.jobQueueName
    从类型 JOB_INITED,我想要 event.JobInited.{launchTime, totalMaps, totalReduces}

    jq --raw-output '
      map(
        select(.type == "AM_STARTED").event.AMStarted.startTime,
        select(.type == "JOB_QUEUE_CHANGED").event.JobQueueChange.jobQueueName,
        select(.type == "JOB_INITED").event.JobInited["launchTime", "totalMaps", "totalReduces"]
      )
    | @csv'
    

    试试here


    这是更新问题的答案:

    从类型 AM_STARTED 'json/index/row',我想要 event.AMStarted.startTime
    忽略 TASK_STARTED - 我不想要任何类型中有“TASK”的东西
    从 JOB_INITED,我想要所有字段
    从 JOB_FINISHED,我想要完成时间,以及 FILE_BYTES_READ 和 FILE_BYTES_WRITTEN 的值

    jq --raw-output '
      map(
        select(.type == "AM_STARTED").event.AMStarted.startTime,
        select(.type == "JOB_INITED").event.JobInited[],
        (
          select(.type == "JOB_FINISHED").event.JobFinished
          | .finishTime,
          (
            .totalCounters.groups[].counts[] | (
              select(.name == "FILE_BYTES_READ").value,
              select(.name == "FILE_BYTES_WRITTEN").value
            )
          )
        )
      )
      | @csv
    ' 
    

    试试here

    【讨论】:

    • 如何选择不同嵌套级别的多个字段?请参阅上面的更新问题(BYTES_READ & WRITTEN)
    • 我更新了答案。
    猜你喜欢
    • 2016-01-08
    • 1970-01-01
    • 1970-01-01
    • 2021-04-09
    • 1970-01-01
    • 1970-01-01
    • 2018-02-03
    • 2018-03-13
    • 2018-07-23
    相关资源
    最近更新 更多