【问题标题】:How to extract contents of a large text file that appears to editors as only one line如何提取对编辑器仅显示为一行的大文本文件的内容
【发布时间】:2017-05-15 05:07:34
【问题描述】:

我想从对编辑器显示为一行的大型 JSON 文件中提取内容(因此我不能以行为基础进行操作),例如

{"license": 2, "file_name": "COCO_test2014_000000523573.jpg", "coco_url": "http://mscoco.org/images/523573", "height": 500, "width": 423, "date_captured": "2013-11-14 12:21:59", "id": 523573}, {"license . . .

例如,有没有办法(sed、grep、...?)我可以搜索单词 000000523573 并打印该单词出现之前的 100 个字符和之后的 200 个字符?

【问题讨论】:

  • 能否请您附上您迄今为止生成的代码、您获得的结果以及您所追求的结果示例?查看MCVE 说明和 SO 的“How To Ask”,了解如何将这个问题变成一个好问题的指南。

标签: text sed grep


【解决方案1】:

data.txt:

{"license": 2, "file_name": "COCO_test2014_000000523573.jpg", "coco_url": "http://mscoco.org/images/523573", "height": 500, "width": 423, "date_captured": "2013-11-14 12:21:59", "id": 523573}, {"license": 2, "file_name": "COCO_test2014_000000523574.jpg", "coco_url": "http://mscoco.org/images/523574", "height": 500, "width": 423, "date_captured": "2013-11-14 12:21:59", "id": 523574}

命令:

cat data.txt | sed 's/\},\s{/}\n{/g' | grep "000000523573"

输出:

{"license": 2, "file_name": "COCO_test2014_000000523573.jpg", "coco_url": "http://mscoco.org/images/523573", "height": 500, "width": 423, "date_captured": "2013-11-14 12:21:59", "id": 523573}

【讨论】:

    【解决方案2】:

    jq 是您想要用于本地解析 JSON 的工具。如果是结构化格式,请不要将其视为随机文本。

    $ jq . < input.json
    {
      "license": 2,
      "file_name": "COCO_test2014_000000523573.jpg",
      "coco_url": "http://mscoco.org/images/523573",
      "height": 500,
      "width": 423,
      "date_captured": "2013-11-14 12:21:59",
      "id": 523573
    }
    $ jq .height < input.json
    500
    

    要在 file_name 记录中搜索包含特定字符串的特定 JSON 记录,您可以执行以下操作:

    jq 'select(.file_name|contains("000000523573"))' < input.json
    

    这里的符号……解释起来比单个 SO 答案更有意义。如果您有兴趣使用此工具,请查看 JQ 查询结构。

    【讨论】:

    • +1 不错的解决方案...请注意 jq 必须安装,因为它在任何系统中默认不存在
    • @FlashThunder - 是的,绝对的。我提供链接的原因之一。 :)(我不知道你在哪个平台上,但我希望你应该能够在你友好的社区包存储库中找到 jq。)
    【解决方案3】:

    正如ghoti's answer 中所展示的,jq 绝对是您的最佳选择。

    至于您的确切问题(“搜索单词000000523573 并打印前面的100 个字符和后面的200 个字符”):您可以使用grep -o,如下所示:

    grep -Eo '.{100}000000523573.{200}' infile
    

    这有一些缺点:

    • 如果000000523573 出现早于文件开头的 100 个字符或晚于文件结尾的 200 个字符,它将被忽略。
    • 如果两次出现之间的距离小于 300 个字符,则后面的出现将被忽略(grep -o 不考虑重叠出现)。

    这些可以通过放宽“在出现之前/之后打印最多 100/200个字符”的要求在某种程度上得到缓解:

    grep -Eo '.{,100}000000523573.{,200}' infile
    

    但是,同样,正确的方法是使用 jq。另见this question about command line JSON parsing

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-30
      • 2020-07-05
      • 2021-11-26
      • 1970-01-01
      相关资源
      最近更新 更多