簡體   English   中英

Python:輸入文件就是輸出文件

[英]Python: input file is output file

我想使用python編寫某種文件解析器。 它應逐行讀取文件,必要時進行一些替換,然后將“ new”行寫入輸出文件。 它應該從命令行調用(作為我的C構建過程的一部分)。

我已經擁有的東西很好,可以像

python convert.py -i input.txt -o output.txt

但是,由於此解析器不是要創建新文件而是要修改現有文件,因此該解決方案令人失望。 我想將腳本更改為像

python convert.py textfile.txt

我所知道的是我無法打開文件進行讀寫,因為open(myFile“ w”)會刪除該文件。 那么,什么是最好的進行方式?

  • 解析整個文件,將其關閉,進行轉換,然后打開文件進行寫入? 這將需要將所有數據存儲在內存中。 一個文件最多可以包含15.000行
  • 寫入臨時文件,處理后刪除輸入文件,重命名臨時文件? 感覺有點奇怪。
  • 將輸出寫到stdout而不是輸出文件? 然后可以使用>或|之類的流運算符。 從命令行。

但是,我嘗試了這個:

python convert.py textfile.txt > textfile.txt

結果是一個空文件。 以下工作:

python convert.py textfile.txt > textfile2.txt

因此,如果文件是由我的腳本打開的,我認為>運算符將無法正常工作。 但是,如果可以避免使用命令行流運算符,我會感到更加高興。

有什么建議么?

您可以打開兩個文件,讀取原始文件,對數據進行處理,然后將其寫入新文件。 最后,將新文件移到舊文件。 這樣,您可以逐行讀取,而不必將所有內容都存儲在內存中。

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')

我會從你的問題中倒退。

python convert.py textfile.txt > textfile.txt

> shell運算符將打開目標文件以立即寫入,該文件隨后立即截斷該文件,然后輸入uh,0字節。

  • 寫入臨時文件,處理后刪除輸入文件,重命名臨時文件? 感覺有點奇怪。

sed (命令行實用程序)實際上就是這樣做的。 閱讀sedinfo條目,找到-i

`-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)).

因此,當一個使用率很高的實用程序以這種方式進行操作時,您可以確定這可能是您想要做的明智的方式。

無論如何,只要使用@nouseforname提供的解決方案即可。


如果考慮一下,文件基本上就是磁盤上連續字節的流。 如果您的更改涉及刪除然后添加不同數量的字節,那么該怎么做? 答案是,您必須在下一個段的開頭將一些字節重寫到新位置,一旦到達該點,為什么不將其存儲在其他位置? 喜歡其他檔案嗎?

...當然,有人可以實現透明地處理此問題的文件系統,但通常不會這樣做。

也就是說,如果您的更改不會更改文件的總長度,則有一種可能的方法。 您可以為此使用mmap模塊,我將毫不客氣地竊取他們的示例

import mmap

# write a simple example file
with open("hello.txt", "wb") as f:
    f.write("Hello Python!\n")

with open("hello.txt", "r+b") as f:
    # memory-map the file, size 0 means whole file
    mm = mmap.mmap(f.fileno(), 0)
    # read content via standard file methods
    print mm.readline()  # prints "Hello Python!"
    # read content via slice notation
    print mm[:5]  # prints "Hello"
    # update content using slice notation;
    # note that new content must have same size
    mm[6:] = " world!\n"
    # ... and read again using standard file methods
    mm.seek(0)
    print mm.readline()  # prints "Hello  world!"
    # close the map
    mm.close()

因此,有一種方法,但是通常在替換文件中的文本時,這種“相同大小”的假設是不正確的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM