jq:根据不同(计算)值提取值

时间:2017-08-15 19:27:03

标签: json bash date select jq

我正在尝试将一个非常大的json文件(来自aws rds describe-db-snapshots的AWS输出)过滤到一个快照列表中以进行删除。

最终的快照列表应该超过60天。我可以通过SnapshotCreateTime来识别他们的年龄,但我需要他们的DBSnapshotIdentifier值才能删除它们。

为了SO的目的大大剥离,下面是input.json文件。

{
  "Engine": "postgres",
  "SnapshotCreateTime": "2017-08-22T16:35:42.302Z",
  "AvailabilityZone": "us-east-1b",
  "DBSnapshotIdentifier": "alex2-20170822-0108-bkup",
  "AllocatedStorage": 5
}
{
  "Engine": "postgres",
  "SnapshotCreateTime": "2017-06-02T16:35:42.302Z",
  "AvailabilityZone": "us-east-1a",
  "DBSnapshotIdentifier": "alex-dbs-16opfr84gq4h9-snapshot-rtsmdbinstance-fr84gq4h9",
  "AllocatedStorage": 5
}
{
  "Engine": "postgres",
  "SnapshotCreateTime": "2017-04-22T16:35:42.302Z",
  "AvailabilityZone": "us-east-1a",
  "DBSnapshotIdentifier": "alex3-20170422-update",
  "AllocatedStorage": 5
}

我知道select,但据我所知,它无法处理单行中时间比较所需的数学运算。我认为我需要扩展到bash,所以我一直在搞乱以下(笨重)的解决方法。它没有用,但我认为我把它作为努力的证据。

THEN=$(date +'%Y%m%d' -d "`date`-60days")

while IFS= read -r i
    do
        awsDate=$(jq -r '.SnapshotCreateTime' < $i) // get time
        snapDate=$(date -d $awsDate +'%Y%m%d') //convert to correct format

        if [ $snapDate -gt $THEN ] //compare times
        then
            // something to copy the ID

        fi

    done < input.json

在这种情况下,我正在寻找

的输出
alex-dbs-16opfr84gq4h9-snapshot-rtsmdbinstance-fr84gq4h9
alex3-20170422-update

2 个答案:

答案 0 :(得分:2)

这是一个全jq解决方案(即不依赖于调用date命令的解决方案)。您可能想尝试一种变体,例如使用--arg之类的命令行选项传递某种形式的日期。

jq目前还不太了解SnapshotCreateTime格式;这就是对sub的调用的来源:

def ago(days): now - (days*24*3600);

select(.SnapshotCreateTime | sub("\\.[0-9]*";"") < (ago(60) | todate))
| .DBSnapshotIdentifier

在修复示例输入以使其有效JSON之后,输出将为:

"alex-dbs-16opfr84gq4h9-snapshot-rtsmdbinstance-fr84gq4h9"
"alex3-20170422-update"

要剥离引号,请使用-r命令行选项。

答案 1 :(得分:0)

这是一个定义过滤函数的解决方案,该函数使用 select sub fromdate now

def too_old:
    select(   .SnapshotCreateTime
            | sub("[.][0-9]+Z";"Z")   # remove fractional seconds
            | fromdate                # convert to unix time
            | now - .                 # convert to age in seconds
            | . >  (86400 * 60)       # true if older than 60 days in seconds
    )
;

  too_old
| .DBSnapshotIdentifier

如果您将其放在文件filter.jq中并使用-r选项运行jq,例如

jq -M -r -f filter.jq input.json

它将产生您请求的输出:

alex-dbs-16opfr84gq4h9-snapshot-rtsmdbinstance-fr84gq4h9
alex3-20170422-update