为了账号安全,请及时绑定邮箱和手机立即绑定

如何使用 shell 脚本/ ANT 脚本/ java 代码/ python 代码修改 zip

如何使用 shell 脚本/ ANT 脚本/ java 代码/ python 代码修改 zip

牧羊人nacy 2023-07-27 09:57:18
我需要修改 zip 文件内的 json 文件内的 json 内容。zip 文件的层次结构是:abc.zip文件夹1数据库配置配置1.xml配置2.xml文件文件夹JSON文件夹所有包含 json 对象的 json 文件jsonobjects.zip我需要使用与现有 json 格式不同的格式修改 json 对象。json 文件中现有的 JSON 对象是:{ "title":"xyz",  "type":"object", "properties":{ "id":"123", "name":"xyz"}}json 文件中应替换的新内容应为:{  "name":"xyz"  "type":"JSON"  "schema":{ // entire content of the existing JSON should be there in schema  "title":"xyz",   "type":"object",  "properties":{ "id":"123", "name":"xyz"}   }  "owner":"jack"}哪个简单有效地完成这个任务(shellscript / python脚本/ java代码)?
查看完整描述

1 回答

?
aluckdog

TA贡献1847条经验 获得超7个赞

考虑到该文件很小(低于 1MB),使用下一个简单的 Python 脚本就足够了(对于如此小的数据来说速度会非常快)。

我使用了zipfile.ZIP_DEFLATEDzip 文件最常见的压缩方式。zipfile.ZIP_STORED如果您需要内部未压缩的文件,您可以使用它。或者 zipfile.ZIP_BZIP2 和 zipfile.ZIP_LZMA 用于其他压缩算法。仅需要为输出/处理的 zip 设置压缩类型,自动导出输入 zip 压缩。zipfilejson都是io标准的python模块,不需要安装任何东西。

fin.zipfout.zip是示例输入/输出 zip 文件名。您需要一个单独的输出/处理的 zip 文件,并且无法就地修改输入 zip,因为 JSON 文件会更改其大小,并且输入 zip 也可能被压缩,因此需要重新打包/重新压缩到另一个输出 zip 文件。此外,输入和输出 zip 文件名可能相同,然后输入文件将被替换,但在这种情况下,不要忘记备份 zip,直到您确定 zip 转换没有错误。

您可以看到对象被修改的行jdata,您可以根据任务需要的方式更改它们。jdata 从 json 解码然后修改,然后编码回 json。另请注意,如果您需要限制扩展条件,则整个层次结构中的所有 json 和 zip 文件都将被修改elif fname.endswith('.json')

看起来您已将拉链嵌套在另一个拉链内。这就是为什么我创建了一个单独的ProcessZip()函数,以便递归地调用它来处理嵌套的 zip,它可以处理任何嵌套级别。

更新:我添加了 xml 到 json 转换的示例。它需要xmltodict通过命令安装模块python -m pip install xmltodict。此外,由于 xml 可能以不同的方式转换为 json(例如 json 没有属性),因此您可能还需要按照您需要的方式修复转换后的内容。另请注意,从 xml 转换后,我将压缩文件扩展名从 更改.xml.json.

import zipfile, json, io

# Needs: python -m pip install xmltodict

import xmltodict


def ProcessZip(file_data):

    res = io.BytesIO()

    with zipfile.ZipFile(io.BytesIO(file_data), mode = 'r') as fin, \

         zipfile.ZipFile(res, mode = 'w', compression = zipfile.ZIP_DEFLATED) as fout:

        for fname in fin.namelist():

            data = fin.read(fname)

            if fname.endswith('.zip'):

                data = ProcessZip(data)

            elif fname.endswith('.json'):

                jdata = json.loads(data.decode('utf-8-sig'))

                # Check that we don't modify already modified file

                assert 'schema' not in jdata, 'JSON file "%s" already modified inside zip!' % fname

                # Modify JSON content here

                jdata = {

                    'name': 'xyz',

                    'type': 'JSON',

                    'schema': jdata,

                    'owner': 'jack',

                }

                data = json.dumps(jdata, indent = 4).encode('utf-8')

            elif fname.endswith('.xml'):

                jdata = xmltodict.parse(data)

                jdata = {

                    'name': 'xyz',

                    'type': 'JSON',

                    'schema': jdata,

                    'owner': 'jack',

                }

                data = json.dumps(jdata, indent = 4).encode('utf-8')

                fname = fname[:fname.rfind('.')] + '.json'

            fout.writestr(fname, data)

    return res.getvalue()


with open('fin.zip', 'rb') as fin:

    res = ProcessZip(fin.read())

with open('fout.zip', 'wb') as fout:

    fout.write(res)


查看完整回答
反对 回复 2023-07-27
  • 1 回答
  • 0 关注
  • 66 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信