如果已经存在,请不要追加

时间:2018-03-19 21:39:13

标签: python python-3.x python-2.7

我有一个名为ClientList.txt的文件,其输出为:

client1.hello.com
client2.hello.com
client3.hello.com

我使用此脚本将ClientList.txt的值附加到output.txt文件中。代码:

with open("ClientList.txt", "r") as infile:
  with open("output.txt", "a") as outfile:
    for line in infile:
        outfile.write("".join(["clients name: ",line.strip(), ", clients URL: ", line.strip(), ", service: VIP\n"]))

输出:

clients name: client1.hello.com, clients URL: client1.hello.com, service: VIP
clients name: client2.hello.com, clients URL: client2.hello.com, service: VIP
clients name: client3.hello.com, clients URL: client3.hello.com, service: VIP

问题:将来我想用新客户更新ClientList.txt(例如:client4.hello.com等)。如果值已存在于output.txt文件中,是否可以附加值?

4 个答案:

答案 0 :(得分:0)

文件只是简单的文本流,因此它们不支持“如果不存在等效行,则附加此行”的任何概念;你必须手动构建它。

可以只使用纯文本文件来执行此操作,但它很笨拙且可能效率低下。你要做的就是通读文件并自己检查。您可以通过读取文件一次并将其存储在一组而不是一遍又一遍地进行优化来优化它,但它仍然有点难看:

with open("ClientList.txt", "r") as infile:
    with open("output.txt", "r") as outfile:
        existing = set(outfile)
    with open("output.txt", "a") as outfile:
        for line in infile:
            outline = "".join(["clients name: ",line.strip(), ", clients URL: ", line.strip(), ", service: VIP\n"])
            if outline not in existing:
                outfile.write(outline)
                existing.add(outline)

如果您想知道set(outfile)是如何工作的:Python中的文件对象是可迭代的行。这就是for line in infile:有效的原因。这意味着我们可以通过将该迭代传递给set来构造所有行的集合。

使用数据库可能会更好。

最简单的数据库可能是内置于Python的dbm格式,其工作方式与Python字典很相似。就像你不能多次在dict中存储相同的键(重复只是覆盖原始)一样,dbm也是如此。所以:

with open("ClientList.txt", "r") as infile:
    with dbm.open("output.dbm", "c") as outfile:
        for line in infile:
            outline = "".join(["clients name: ",line.strip(), ", clients URL: ", line.strip(), ", service: VIP\n"])
            outfile[outline] = ""

或者,更好的是,实际上使用键值。如果它是clients name而不是整个字符串必须是唯一的,那就把它作为密钥,其余的就是值:

with open("ClientList.txt", "r") as infile:
    with dbm.open("output.dbm", "c") as outfile:
        for line in infile:
            outline = json.dumps({
                "clients name": line.strip(),
                "clients URL": line.strip(),
                "service": "VIP"})
            outfile[clients_name] = outline

然后,当然,您的输出是dbm数据库而不是文本文件,只有在消耗数据的内容知道如何使用dbm时才能生效。但是,如果你正在编写消耗数据的东西,那应该不是问题。

当然,您有多个值与每个键关联,因此理想的解决方案可能是多列键值数据库,文档数据库或关系数据库。 Python附带了一个名为sqlite3的简单关系数据库,你可以使用这样的东西(未经测试):

with open("ClientList.txt", "r") as infile:
    db = sqlite3.connect('output.sqlite')
    db.execute('''CREATE TABLE IF NOT EXISTS Clients COLUMNS (
        Name TEXT PRIMARY KEY,
        URL TEXT,
        Service TEXT)''')
    for line in infile:
        db.execute('''INSERT OR IGNORE INTO Clients (Name, URL, Service)
            VALUES (?, ?, ?)''', (line.strip(), line.strip(), 'VIP'))

答案 1 :(得分:0)

只要文件大小不是太大,我就可以使用最简单的解决方案,只需将数据读入内存,更改文件,然后将其写回。这在python中非常简单,但仍然很快。

with open('ClientList.txt') as f:
    data = set(f.readlines())
data.add('nextValue\n')
with open('ClientList.txt', 'w') as f:
    f.writelines(data)

答案 2 :(得分:0)

你可以添加这样的验证:` def存在(file_name,link):     使用open(file_name)作为tmp:         对于tmp中的行:             如果链接在行:                 返回True     返回False

以open(“ClientList.txt”,“r”)为infile: 使用open(“output.txt”,“a”)作为outfile:     对于infile线:         如果不存在('output.txt',行):             outfile.write(“”。join([“clients name:”,line.strip(),“,clients URL:”,line.strip(),“,service:VIP \ n”])) ` 即使每次关闭和打开文件都可能不是一个好主意,你可以修改函数,以便保持对文件的引用,你只需要在开头移动指针并再次开始搜索,你可以也有内存中的所有内容并直接在那里进行搜索,但这项工作将是您的决定

答案 3 :(得分:-1)

当然,您可以检查客户端的名称是否在output.txt中,如:

with open("ClientList.txt", "r") as infile:
  with open("output.txt", "a") as outfile:
    file=outfile.read()
    for line in infile:
        clientName=line.strip()
        if (clientName in file)==False:
            outfile.write("".join(["clients name: ",line.strip(), ", clients URL: ", line.strip(), ", service: VIP\n"]))

不确定这是否有效,但应该这样做。