【问题标题】:Delete blank/empty lines in text file for Python [closed]删除 Python 文本文件中的空白/空行 [关闭]
【发布时间】:2021-02-18 16:19:21
【问题描述】:

我有一个包含内容的文本文件:

Line 1
,
,
Line 2
,
Line 3
,
Line 4

我想创建一个函数来删除行之间的空格(用 标记,用于说明)

到目前为止,我已经使用以下代码创建了一个函数,但是当我运行它时没有任何反应:

with open('path/to/file.txt', 'r') as f: 
    for line in f:           
        line = line.strip()  

感谢任何帮助。

【问题讨论】:

  • 即使它会去除线条,但在这里它不会,因为您遍历线条,您不会将值存储在(另一个)文件中。
  • 您可能希望将结果写入另一个文件,只要if line:
  • 有没有办法从现有文件中删除空白行而不写入新文件?
  • 您不能“编辑”文件,只能读取、追加或写入文件
  • 您可以将整个文件读入内存,关闭文件,再次打开写入,然后从内存中写入新内容。

标签: python


【解决方案1】:

如果您想从现有文件中删除空白行而不写入新文件,您可以在读写模式下再次打开同一个文件(由'r+' 表示)进行写入。写入完成后在写入位置截断文件:

with open('file.txt') as reader, open('file.txt', 'r+') as writer:
  for line in reader:
    if line.strip():
      writer.write(line)
  writer.truncate()

演示:https://repl.it/@blhsing/KaleidoscopicDarkredPhp

【讨论】:

  • 这个答案太好了,直接回答问题
【解决方案2】:

line.strip() 只会删除 that 行,但这并不意味着如果该行为空,则该行会以某种方式消失。此外,您永远不会将(已处理的)行真正存储在(另一个)文件中。

您可以处理该文件并将结果写入target.txt 文件:

with open('path/to/file.txt', 'r') as f:
    with open('path/to/target.txt', 'w') as w:
    for line in f:
        if line.strip():
            w.write(line)

如果您也想去除非空行,因此从所有行中删除前导和尾随空格,您可以使用剥离变体:

with open('path/to/file.txt', 'r') as f:
    with open('path/to/target.txt', 'w') as w:
    for line in f:
        line = line.strip()
        if line:
            w.write(line)
            w.write('\n')

这个程序会逐行读取文件,这对于大文件来说通常更好,因为在内存中加载一个大文件会导致内存问题。

此外,最好将结果存储在另一个文件中。如果机器在处理过程中崩溃(例如由于电源故障),那么您仍然拥有原始文件。大多数 Linux 命令旨在写入另一个文件。这样稍后,当操作完成时,您将目标移动到原始文件。

【讨论】:

  • 这很有道理,谢谢。在您的示例中,我将如何将更改写回原始文件。我可以将 target.txt 替换为 file.txt
  • @Rutnet:在这种情况下,您最好将新文件移动到源文件处理后,例如使用os.rename。从那时起,您的内存使用率仍然很低,此外,如果机器在写入时出现故障,您将始终拥有原始文件或结果文件,但不是半处理的东西(因此其余内容丢失)。
  • 令人惊叹,完美运行
  • @WillemVanOnsem 第二种解决方案将错误地去除所有换行符,因此输出变成一长行。
  • @blhsing:谢谢,更新了。
【解决方案3】:

如果您想从现有文件中删除空白行而不写入新文件,则可以改用随机访问。以读写二进制模式打开文件,逐行读取时使用file.tell方法跟踪文件的读取位置,写入非空行时跟踪文件的写入位置,恢复读取和使用file.seek方法读写时写入位置,最后使用file.truncate方法在最后一个写入位置截断文件:

write_position = 0
with open('file.txt', 'rb+') as f:
  for line in f:
    if line.strip():
      read_position = f.tell()
      f.seek(write_position)
      f.write(line)
      write_position = f.tell()
      f.seek(read_position)
  f.truncate(write_position)

演示:https://repl.it/@blhsing/UncommonRevolvingTransversals

【讨论】:

    【解决方案4】:
    with open('path/to/file.txt', 'r') as f: #this opens the file in read mode
        lines = [line for line in f.readlines() if line.strip() != ""] #this puts all the lines of the file into a nice list, but removes every line that is empty. 
    
    with open('path/to/file.txt', 'w') as f: #this just clears the contents
        pass 
    
    for line in lines: #this goes through the lines list
        with open('path/to/file.txt', 'a') as f: #this opens the file append mode
            f.write(f'{line.strip()}\n') #this strips the line, and adds it at the end of the file and creates a new line
    

    【讨论】:

    • 你。不需要经历这一切。如果您只是以 'w' 模式打开文件,然后对其进行写入,那么之前文件中的内容无关紧要。不需要先清除它。无需使用附加模式。
    【解决方案5】:

    您可以像这样删除空行:

    with open("txt.txt", "r") as f:
      for l in f:
        if l == "\n":
          l = l.replace("\n", "")
        with open("output.txt", "a") as f2:
            f2.write(l)
    

    【讨论】:

      【解决方案6】:

      我会这样处理:

      with open('path/to/file.txt', 'r+') as f:
          lines = f.readlines()
          lines = [line.strip() for line in lines]
          f.writelines(line)
      

      【讨论】:

        【解决方案7】:

        修改后需要覆盖文件:

        with open('path/to/file.txt', 'r') as f:  
            new_text = '\n'.join([line.strip() for line in f.read().split('\n')] if line.strip())
            with open('path/to/file.txt','w') as in_file: 
                in_file.write(new_text)
        

        【讨论】:

        • 注意这会将整个文件加载到内存中,如果文件很大,很容易耗尽整个内存。
        • 好的,谢谢……你也教我……你的答案似乎比我的更正确……
        猜你喜欢
        • 2013-08-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-09-22
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多