【问题标题】:Replace URLs in JSON file using shell/bash or python?使用 shell/bash 或 python 替换 JSON 文件中的 URL?
【发布时间】:2020-12-27 11:22:49
【问题描述】:

我有一个简单的 JSON 文件,我们从一个看起来像这样的工件下载它:

movie_list.json

{
  "config": {
    "platform": {
      "api": "artifactory", 
      "url": "https://disney-europe.artifactory.com/myhome"
    }
  }, 
  "packages": {
    "platform": [
      "/netflix-australia/donkey_kong/random1.rpm", 
      "/netflix-australia/donkey_kong/random2.rpm"
    ]
  }
}

所以基本上,我需要读取这个 JSON 文件并替换(删除欧洲后缀):

https://disney-europe.artifactory.com/myhome 与 -> https://disney.artifactory.com/myhome

和(去掉澳大利亚后缀):

/netflix-australia/donkey_kong/random1.rpm 与 -> /netflix/donkey_kong/random1.rpm

在 python 中使用 REGEX 最容易做到这一点吗?还是 bash/shell?

我之前在 Java 中使用过正则表达式,但在 .json 文件和 Linux 机器上使用的不是很多(这台机器确实安装了 python,所以如果更容易我可以使用它)

谢谢。

【问题讨论】:

  • 替换只发生在某些字段还是每个字段?是否只有europe & australia 需要更换?

标签: python json regex bash parsing


【解决方案1】:

在这种情况下,我建议避免使用 REGEX。由于您确切知道需要更改的字符串,因此 KISS 原则建议依赖字符串的 replace 方法,因为它是一种不太复杂的方法。

with open('old_file.txt', 'r') as infile:
    indata = infile.read()

# Replace the target string
formatted_data = indata.replace('disney-europe', 'disney').replace('netflix-australia', 'netflix')

# Write the file out again
with open('new_file.txt', 'w') as outfile:
      outfile.write(formatted_data)

如果您不想保留原始数据,也可以覆盖原始文件。

但是,由于您特别询问了使用 REGEX,您可以执行以下操作:

import re

# Define what should be replaced
replacements = {"disney-europe": "disney", "netflix-australia": "netflix"} 
replacements = dict((re.escape(k), v) for k, v in replacements.items()) 

# Replace any occurences in the file
pattern = re.compile("|".join(replacements.keys()))
with open('old_file.txt', 'r') as infile:
    indata = infile.read()

# This gives the new json data
formatted_data = pattern.sub(lambda m: replacements[re.escape(m.group(0))], indata)

编辑以响应 cmets:

使用 REGEX 的缺点(在这种情况下)是您需要增加一层复杂性来支持您不需要的其他功能(即 REGEX 模式匹配功能)。这意味着您不仅要针对控制流中的错误测试您的代码,还要针对格式错误的正则表达式或意外文本输入等问题进行测试。总体而言,需要更多的工作和更多的管理,而性能几乎没有改善。

【讨论】:

  • 我只想解释为什么你认为正则表达式在这里不好,而不是展示它仍然可以如何完成
【解决方案2】:

由于您正在处理 JSON,您可能希望使用 jq;这样做的好处是它允许您准确定位 JSON 中要进行更改的位置。

这实际上取决于您对数据的了解程度以及您需要做出的更改的具体程度是最佳方法,但使用 jq 的一个简单示例可能是:

$ cat your-data | jq '.config.platform.url |= if . == "https://disney-europe.artifactory.com/myhome" then "https://disney.artifactory.com/myhome" else . end | .packages.platform[] |= gsub("/netflix-australia/donkey_kong/";"/netflix/donkey_kong/")'
{
  "config": {
    "platform": {
      "api": "artifactory",
      "url": "https://disney.artifactory.com/myhome"
    }
  },
  "packages": {
    "platform": [
      "/netflix/donkey_kong/random1.rpm",
      "/netflix/donkey_kong/random2.rpm"
    ]
  }
}

您可以根据需要链接任意数量的转换。

这个例子展示了一个相等性测试和一个模式替换,但是 jq 有许多其他你可能会发现更合适的函数。

【讨论】:

    猜你喜欢
    • 2014-02-09
    • 2015-11-25
    • 2016-04-21
    • 2017-01-27
    • 1970-01-01
    • 1970-01-01
    • 2021-09-17
    • 2018-07-23
    • 2011-12-07
    相关资源
    最近更新 更多