使用Python编辑文本文件
我需要在我的IP地址变化时更新一个文本文件,然后再从命令行运行几个命令。
首先,创建一个变量 LASTKNOWN = "212.171.135.53"。这个是我们在写这个脚本时的IP地址。
获取当前的IP地址。这个地址每天都会变化。
为新的IP地址创建一个变量 CURRENT。
将 CURRENT 和 LASTKNOWN 进行比较(当作字符串比较)。
如果它们是一样的,就退出程序。
如果它们不一样,
A. 将包含 LASTKNOWN IP 地址的旧配置文件 (/etc/ipf.conf) 复制到 /tmp 文件夹。
B. 在 /tmp/ipf.conf 文件中将 LASTKNOWN 替换为 CURRENT。
C. 使用子进程命令 "mv /tmp/ipf.conf /etc/ipf.conf" 来移动文件。
D. 使用子进程命令执行 "ipf -Fa -f /etc/ipf.conf"。
E. 使用子进程命令执行 "ipnat -CF -f /etc/ipnat.conf"。最后,退出程序。
我知道如何完成步骤1到6,但在“文件编辑”部分(A到C)遇到了困难。我不知道该用哪个模块,或者是否应该直接在文件中编辑。方法有很多,我无法决定哪种方式最好。我想要一种比较保守的方法。
我知道如何使用子进程,所以你不需要对此进行评论。
我不想替换整行,只想替换特定的IP地址。
谢谢!
6 个回答
把 /etc/ipf.conf 文件中的 LASTKNOWN 替换成 CURRENT
一次性替换所有
filename = "/etc/ipf.conf"
text = open(filename).read()
open(filename, "w").write(text.replace(LASTKNOWN, CURRENT))
逐行替换
from __future__ import with_statement
from contextlib import nested
in_filename, outfilename = "/etc/ipf.conf", "/tmp/ipf.conf"
with nested(open(in_filename), open(outfilename, "w")) as in_, out:
for line in in_:
out.write(line.replace(LASTKNOWN, CURRENT))
os.rename(outfilename, in_filename)
注意:"/tmp/ipf.conf" 应该用 tempfile.NamedTemporaryFile()
或类似的东西替代
注意:这个代码没有经过测试。
另一种简单地在原地编辑文件的方法是使用 fileinput
模块:
import fileinput, sys
for line in fileinput.input(["test.txt"], inplace=True):
line = line.replace("car", "truck")
# sys.stdout is redirected to the file
sys.stdout.write(line)
fileinput模块的接口设计得很糟糕,我找到一个更好用的模块来完成这个任务 - in_place,下面是Python 3的一个例子:
import in_place
with in_place.InPlace('data.txt') as file:
for line in file:
line = line.replace('test', 'testZ')
file.write(line)
这个模块和fileinput的主要区别在于:
- 它不是通过劫持sys.stdout来工作的,而是返回一个新的文件句柄供你写入。
- 这个文件句柄支持所有标准的输入输出方法,而不仅仅是readline()。
举个例子,fileinput只能逐行编辑,而in_place可以把整个文件读到内存中(如果文件不大),然后进行修改。