2017-08-15 38 views
1

我試圖篩選一個非常大的json文件(AWS輸出從aws rds describe-db-snapshots)到僅用於刪除的快照列表中。jq:基於不同(計算)值的提取值

快照的最終列表應該早於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但是從我可以告訴它不能處理需要在一個班輪時間比較數學。我想我需要分手,所以我一直在搞亂以下(笨拙的)解決方法。這不起作用,但我想我會把它作爲努力的證明。

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 
+0

小JSON的問題:你應該''AllocatedStorage':5,'鍵/值對中的'5'之後沒有尾隨逗號。 – jq170727

+0

@ jq170727感謝您的理解,簡化中的錯誤不在實際數據中。編輯! – Alex

回答

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命令行選項。

0

下面是其中定義了一種利用選擇沒有fromdate現在的濾波器功能的解決方案。

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和運行JQ與-r選項如

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

就會產生你所要求的輸出:

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