我要从文件中删除某些特定行。假设这是第20-37行,然后是第45行。如果不指定这些行的内容,该怎么办?
我要从文件中删除某些特定行。假设这是第20-37行,然后是第45行。如果不指定这些行的内容,该怎么办?
Answers:
使用sed
,如下所示:
sed '20,37d; 45d' < input.txt > output.txt
如果您想就地执行此操作:
sed --in-place '20,37d; 45d' file.txt
This option specifies that files are to be edited in-place. GNU
sed'通过创建一个临时文件来完成此操作并将输出发送到此文件,而不是发送到标准输出。`...我不知道任何其他“ sed”,但使用流编辑器更新“就地”的后勤工作不“计算” :)
如果文件适合存储在内存中,则也可以使用ed
。
这些命令与sed
上面的命令非常相似,但有一个显着的区别:您必须以降序传递要删除的行号/范围列表(从最高的行号/范围到最低的行号/范围)。原因是,当您使用删除/插入/分割/合并行时ed
,在每个子命令之后都会更新文本缓冲区,因此,如果删除某些行,则当下一个子命令被执行。所以你必须倒退1。
就地编辑:
ed -s in_file <<IN
45d
20,37d
w
q
IN
要么
ed -s in_file <<< $'45d\n20,37d\nw\nq\n'
要么
printf '%s\n' 45d 20,37d w q | ed -s in_file
如果要打印结果输出而不是写入文件,则将w
rite用,p
rint 替换。如果要保持原始文件不变并写入另一个文件,可以将新文件名传递给w
rite子命令:
ed -s in_file <<IN
78,86d
65d
51d
20,37d
w out_file
q
IN
1
除非您愿意在每次d
删除之后计算新的行号,这对于这种特殊情况来说是微不足道的(删除第20-37行,即18行,第45行成为第27行),因此可以运行:
ed -s in_file <<IN
20,37d
27d
w
q
IN
但是,如果您必须删除多个行号/范围,那么倒退工作就很容易了。
q
命令最后有用吗?我想它都会退出。
只需将其读入内存,对其进行更改,然后将其写回即可。你可以做类似的事情
filename = "foo"
f = open(filename, 'r+')
linenums = [1, 3]
s = [y for x, y in enumerate(f) if x not in [line-1 for line in linenums]]
f.seek(0)
f.write(''.join(s))
f.truncate(f.tell())
f.close()
经过5行文件测试。感谢http://pleac.sourceforge.net/pleac_python/fileaccess.html的帮助,请参阅“在没有临时文件的情况下就地修改文件”一节。另请参阅/programming/125703/how-do-i-modify-a-text-file-in-python
一些注意事项:
如上所述,可以先截断文件,然后写入文件,而不是写入,然后截断文件。但是,我不知道一个Python标志允许一个人读取然后进行截断的写入。但是也许我缺少一些东西,因为文档不够清晰。这带给我
有时Python文档确实很烂。请参阅 http://docs.python.org/library/functions.html#open
模式“ r +”,“ w +”和“ a +”打开文件进行更新(请注意,“ w +”会截断文件)。
这对您有什么意义吗?“开放更新”到底是什么?
我不知道在python中这样做,而不是像流编辑器这样的unixy更好。它可能更便携,但我不知道sed的便携性。我之所以这样写是因为,与使用经典的unix工具相比,我对低级编程更满意,如果它们确实可以满足您的要求,则很好,但是(我认为)通常不太灵活。
这种方法(操作内存中的文件)将内存换为磁盘空间。它在具有几Gb内存的机器上可以正常工作,文件大小高达几百Mb。Python不能非常有效地处理字符串,因此,例如切换到C / C ++会稍微提高性能并大大减少内存使用。