Python:输入文件是输出文件

时间:2014-08-19 07:18:17

标签: python file-io command-line

我想用python编写某种文件解析器。 如果需要,它应逐行读取文件,然后写入" new"行到输出文件。 它应该从命令行调用(作为我的C构建过程的一部分)。

我已经拥有的很好,可以像

一样使用
python convert.py -i input.txt -o output.txt

但是,由于此解析器不是为了创建新文件而是为了修改现有文件,因此该解决方案令人失望。 我想将我的脚本更改为

python convert.py textfile.txt

我所知道的是我无法打开文件进行读写,因为打开(myFile" w")将删除该文件。 那么,最好的方法是什么?

  • 解析整个文件,关闭它,进行转换,打开文件进行写入?这将要求将所有数据存储在内存中。文件最多可包含15.000行
  • 写入临时文件,处理后删除输入文件,重命名临时文件?这感觉不知怎的......奇怪。
  • 将输出写入stdout而不是输出文件?然后可以使用像>这样的流运算符。或者来自命令行。

然而,我试过这个:

python convert.py textfile.txt > textfile.txt

,结果是一个空文件。以下是有效的:

python convert.py textfile.txt > textfile2.txt

所以,我认为>如果我的脚本打开文件,则运算符无法正常工作。 但是,如果可以避免使用命令行流操作符,我会更高兴。

有什么建议吗?

2 个答案:

答案 0 :(得分:3)

您可以打开两个文件,阅读原文,对数据执行某些操作,然后将其写入新文件。最后将新文件移动到旧文件。这样你就可以逐行阅读,而不需要全部都在内存中。

import shutil
with open('original.txt') as old, open('newtest.txt', 'w') as new:
    for line in old:
        new.write(line)

shutil.move('newtest.txt', 'original.txt')

答案 1 :(得分:1)

我会从你的问题中倒退。

python convert.py textfile.txt > textfile.txt

> shell操作符打开目标文件立即写入,然后立即截断该文件,然后输入0个字节。

  
      
  • 写入临时文件,处理后删除输入文件,重命名临时文件?这感觉不知怎的......奇怪。
  •   

实际上sed(命令行实用程序)是如何做到的。阅读info的{​​{1}}条目,找到sed

-i

因此,当一个高度使用的实用程序以这种方式执行时,您可以非常肯定这可能是做您想做的事情的理智方式。

无论如何,只需使用@nouseforname提供的解决方案。


如果您考虑一下,您的文件基本上是磁盘上的连续字节流。如果您的更改涉及删除然后添加不同数量的字节,您如何做到这一点?答案是你必须在下一个段的开头重写一些字节到新位置,一旦你到达那一点,为什么不把它藏在不同的位置呢?像一个不同的文件?

...当然,有人可以实现一个透明地处理这个问题的文件系统,但通常情况下还没有完成。

也就是说,如果您的更改不会更改文件的总长度,则会有可能的方式。你可以使用mmap模块,我将无耻地窃取他们的例子

`-i[SUFFIX]'
`--in-place[=SUFFIX]'
     This option specifies that files are to be edited in-place.  GNU
     `sed' does this by creating a temporary file and sending output to
     this file rather than to the standard output.(1).

     This option implies `-s'.

     When the end of the file is reached, the temporary file is renamed
     to the output file's original name.  The extension, if supplied,
     is used to modify the name of the old file before renaming the
     temporary file, thereby making a backup copy(2)).

所以有一种方法,但通常这个"相同的大小"替换文件中的文本时,假设不成立。