jq - 通过搜索关键值

时间:2017-11-22 23:08:13

标签: json jq

数据样本 - shodan_data.json(完整样本:https://pastebin.com/KFkVmc2M

{
      "ip": 3301234701,
      "_shodan": {
        "options": {
          "referrer": "7ae15507-f5cc-4353-b72e-5cc0b1c34c5e"
        },
      },
      "hash": -1056085507,
      "os": null,
      "title": "WHM Login",
      "opts": {
        "vulns": ["!CVE-2014-0160"],
        "heartbleed": "2017/08/29 09:57:30 196.196.216.13:2087 - SAFE\
        }
      },
      "isp": "Fiber Grid Inc",
      "http": {
        "redirects": [],
        "title": "WHM Login",
        "robots": null,
        "favicon": null,
        "host": "196.196.216.13",
        "html":
}

我的jq代码:

jq -r 'select((.opts.vulns[0] | contains("!CVE-2014-0160")))? | ['.ip_str', '.isp', '.timestamp', .opts.vulns[0]] | @csv' shodan_data.json

使用完整数据集时的输出示例:

"165.231.171.237","Fiber Grid Inc","2017-08-22T02:24:07.658547","!CVE-2014-0160"

现在它的作用是搜索具有值.opts.vulns[0]的特定JSON对象!CVE-2014-0160,然后过滤找到值的整个对象并打印指定的对象值{{1}作为csv。还可以抑制未找到可搜索值的任何错误,这些错误允许我将输出写入.csv文件。

我希望它能够获取我想要找到的任何值,例如示例.ip_str', '.isp', '.timestamp', .opts.vulns[0](如搜索引擎),并且能够递归遍历整个JSON数据集并拥有与我的代码atm相同的最终结果。

我一直试图弄清楚这一点,并且一直在尝试!CVE-2014-0160递归下降和其他方法,但我过滤数据的方式似乎表明我想要完成的工作可能需要如果可能的话,采用不同的方法?

1 个答案:

答案 0 :(得分:1)

首先,请放心,如果您可以更精确地制定要求,jq将完成任务。

事实上,以下内容只是您现有内容的一小部分,应符合我目前理解的要求:

case annualBill!:
    if isNumeric {
        let formatter = NumberFormatter()
        formatter.numberStyle = .currency
        formatter.currencySymbol = "$"

        let newString = (textField.text! as NSString).replacingCharacters(in: range, with: string)
        let numberWithOutCommas = newString.replacingOccurrences(of: ",", with: "")
        let number = formatter.number(from: numberWithOutCommas)
        if number != nil {
            let formattedString = formatter.string(from: number!)
            textField.text = formattedString
            values.annualBill = Decimal(string: (textField.text?.digitsOnly)!)
            print(values.annualBill ?? "NA")
        } else {
            textField.text = nil
        }

extension String {
    var digitsOnly: String {
        return components(separatedBy: 
    NSCharacterSet.decimalDigits.inverted).joined(separator: "")
        }
    }

使用pastebin数据,这会产生:

..
| ((.opts.vulns | index("!CVE-2014-0160"))? // empty) as $ix
| [.ip_str, .isp, .timestamp, .opts.vulns[$ix]]
| @csv

(如果你想要一个更复杂的匹配标准,我已经包含了$ ix的计算。)

参数

如果要参数化要搜索的字符串,请在jq程序中将其替换为(例如)"196.196.216.13","Fiber Grid Inc","2017-08-29T06:57:22.546423","!CVE-2014-0160" ,然后像这样调用jq

$string

例如:

jq -r --arg string "!CVE-2014-0160" ......

不知道.isp对象中感兴趣的字符串的位置

jq -r --arg string "!CVE-2014-0160" -f program.jq shodan_data.json