【问题标题】:How to save the increment version number in file using python?如何使用python将增量版本号保存在文件中?
【发布时间】:2019-06-27 08:52:10
【问题描述】:

我正在尝试将 ElasticSearch 的版本保存在一个文件中。

输入文件:

ElasticSearch 5:1:

第一次执行后的输出文件

ElasticSearch 5:1:0

第二次执行后的输出文件

ElasticSearch 5:1:1
ElasticSearch 5:1:0

第三次执行后输出文件

ElasticSearch 5:1:2
ElasticSearch 5:1:1
ElasticSearch 5:1:0

我的代码在下面

import re
reg = r'(?:)$'
with open('elastic.txt', 'r') as fread:
    data = fread.read()
    with open('elastic.txt', 'a') as fwrite:
        fwrite.seek(0,0)
        fwrite.write(re.sub(reg, lambda x: str(int(x.group(0)) + 1), data, 1, re.M))

我面临的两个问题 seek(0,0) 无法正常运行,并且没有添加正则表达式

【问题讨论】:

  • 仅供参考,r'(?:)$' = '$'。它匹配字符串位置的结尾。为什么要增加字符串的结尾?实际的预期结果是什么?
  • 我想从 0 开始保存版本,并在执行时保持递增
  • 试试with open('elastic.txt', 'w') as fwrite:a 代表追加,我很确定你想覆盖它。

标签: python regex file-io


【解决方案1】:

你可以使用

import re
reg = r'\A(.*:)(\d*)$'
with open('elastic.txt', 'r') as fread:
    data = fread.read()
    with open('elastic.txt', 'w') as fwrite:
        fwrite.write(re.sub(reg, lambda x: "{}{}\n{}".format(x.group(1), str(int(x.group(2)) + 1), x.group()) if len(x.group(2)) else "{}0".format(x.group(1)) , data, 1, re.M))

详情

  • \A(.*:)(\d*)$ - 一个正则表达式,如果它具有 :,则在文件开头获取该行,并将直到 : 的部分捕获到第 1 组中,并将任何零个或多个数字捕获到第 2 组中(在行)
  • data是整个文件内容
  • lambda x: "{}{}\n{}".format(x.group(1), str(int(x.group(2)) + 1), x.group()) if len(x.group(2)) else "{}0".format(x.group(1)) 替换为 Group 1、递增的 Group 2 和换行符 + 整个第一行 如果 Group 2 包含数字,否则,它将 0 添加到第一行而不加倍。

【讨论】:

  • 感谢它运行良好。只有一个查询。你如何即兴发挥你的编码技能:)
  • @Mous 如果你想问我是如何学习正则表达式的,我只是每天在 SO 上回答正则表达式问题。 访问 1606 天,连续 1597 天
  • 在上面的表达式中你能告诉我你在哪里检查第一行。例如,如果我的文件有 2 行,假设第二行必须是未触及的示例。 elastic.txt 有 2 行,ElasticSearch 5.1 和 Kibana。而且 Kibana 每次都必须使用 ElasticSearch 进行打印。在这种情况下,我应该提到这些行
  • @Mous (?m)\A(.*:)(\d*)$ 始终匹配第一行,因为\A 是字符串的开头,.* 不能匹配换行符,$ 必须匹配行尾。如果要跳过多行前导行,需要在\A(之后添加(?:.*\n){x}
  • 我已经检查了 \A(.*:)(\d*)$(?:.*\n){x}。如果没有任何作为 ElasticSearch 5.1 一部分的新行没有打印。例如,如果文件具有 ElasticSearch 5:1:0 并且第二行是 Kibana 1.0 并且预期输出必须是 ElasticSearch 5:1:1 和 Kibana 1.0 ,ElasticSearch 5:1:2 和 Kibana 1.0 ,ElasticSearch 5:1:3 和基巴纳 1.0。你能告诉我需要在哪里修改脚本吗
【解决方案2】:

带有自定义incr_patch_version函数的扩展解决方案:

import re

regex = r'(?<=:)\d*$'


def incr_patch_version(fname):
    with open(fname, 'r+') as f:
        lines = f.readlines()
        new_line = re.sub(regex, lambda x: str(int(x.group()) + 1 if x.group().isnumeric() else 0), lines[0])
        f.seek(0)
        f.write(new_line) if lines[0].strip().endswith(':') else f.writelines([new_line, *lines])


fname = 'elastic.txt'

incr_patch_version(fname)
incr_patch_version(fname)
incr_patch_version(fname)
incr_patch_version(fname)

最后的elastic.txt内容:

ElasticSearch 5:1:3
ElasticSearch 5:1:2
ElasticSearch 5:1:1
ElasticSearch 5:1:0

【讨论】:

  • 在上面的表达式中你能告诉我你在哪里检查第一行。例如,如果我的文件有 2 行,假设第二行必须是未触及的示例。 elastic.txt 有 2 行,ElasticSearch 5.1 和 Kibana。而且 Kibana 每次都必须使用 ElasticSearch 进行打印。在这种情况下,我应该提到这些行,下面的代码有效吗? f.write(new_line + lines[1:] ) if lines[0].strip().endswith(':') else f.writelines([new_line, *lines])
  • @Mous,您已将输入文件声明为ElasticSearch 5:1: 行的输入文件。所以第一行应该是“空”补丁号:
  • 如果文件有 ElasticSearch 5:1:0 并且第二行是 Kibana 1.0 并且预期输出必须是 ElasticSearch 5:1:1 和 Kibana 1.0 , ElasticSearch 5:1:2 和 Kibana 1.0 ,弹性搜索 5:1:3 与 Kibana 1.0。我需要写什么表达式。
  • @Mous,因为您已经接受了其中一个答案 - 我假设您已经得到了解决方案,正如您的决定所清楚显示的那样。
  • 是的,它工作正常。但是如果多行是第一行的一部分,我只需要通过第一行并且保持行不变。如果您有想法请在评论中传递,否则非常感谢您抽出宝贵的时间:)
猜你喜欢
  • 2011-10-20
  • 2018-05-04
  • 1970-01-01
  • 1970-01-01
  • 2017-01-29
  • 1970-01-01
  • 2018-03-14
  • 1970-01-01
  • 2020-04-23
相关资源
最近更新 更多