[英]Reproduce the Unix cat command in Python
我目前正在复制以下Unix命令:
cat command.info fort.13 > command.fort.13
在Python中使用以下内容:
with open('command.fort.13', 'w') as outFile:
with open('fort.13', 'r') as fort13, open('command.info', 'r') as com:
for line in com.read().split('\n'):
if line.strip() != '':
print >>outFile, line
for line in fort13.read().split('\n'):
if line.strip() != '':
print >>outFile, line
这是有效的,但必须有一个更好的方法。 有什么建议?
编辑(2016):
四年后,这个问题又开始受到关注。 我在这里用更长的Jupyter笔记本写了一些想法。
这个问题的症结在于我的问题与readlines
的(我意想不到的)行为有关。 我可以更好地回答我的目标,并且使用read().splitlines()
可以更好地回答这个问题。
最简单的方法可能就是忘记行,只需读入整个文件,然后将其写入输出:
with open('command.fort.13', 'wb') as outFile:
with open('command.info', 'rb') as com, open('fort.13', 'rb') as fort13:
outFile.write(com.read())
outFile.write(fort13.read())
正如评论中所指出的,如果任何一个输入很大(因为它首先将整个文件复制到内存中),这可能会导致高内存使用率。 如果这可能是一个问题,以下也可以正常工作(通过以块的形式复制输入文件):
import shutil
with open('command.fort.13', 'wb') as outFile:
with open('command.info', 'rb') as com, open('fort.13', 'rb') as fort13:
shutil.copyfileobj(com, outFile)
shutil.copyfileobj(fort13, outFile)
def cat(outfilename, *infilenames):
with open(outfilename, 'w') as outfile:
for infilename in infilenames:
with open(infilename) as infile:
for line in infile:
if line.strip():
outfile.write(line)
cat('command.fort.13', 'fort.13', 'command.info')
#!/usr/bin/env python
import fileinput
for line in fileinput.input():
print line,
用法:
$ python cat.py command.info fort.13 > command.fort.13
或者允许任意大行:
#!/usr/bin/env python
import sys
from shutil import copyfileobj as copy
for filename in sys.argv[1:] or ["-"]:
if filename == "-":
copy(sys.stdin, sys.stdout)
else:
with open(filename, 'rb') as file:
copy(file, sys.stdout)
用法是一样的。
或者使用os.sendfile()
在Python 3.3上:
#!/usr/bin/env python3.3
import os
import sys
output_fd = sys.stdout.buffer.fileno()
for filename in sys.argv[1:]:
with open(filename, 'rb') as file:
while os.sendfile(output_fd, file.fileno(), None, 1 << 30) != 0:
pass
上面的sendfile()
调用是针对Linux> 2.6.33编写的。 原则上, sendfile()
可能比其他方法使用的读/写组合更有效。
迭代文件会产生线条。
for line in infile:
outfile.write(line)
您可以通过以下几种方式简化此操作:
with open('command.fort.13', 'w') as outFile:
with open('fort.13', 'r') as fort13, open('command.info', 'r') as com:
for line in com:
if line.strip():
print >>outFile, line
for line in fort13:
if line.strip():
print >>outFile, line
更重要的是, shutil模块具有copyfileobj函数:
with open('command.fort.13', 'w') as outFile:
with open('fort.13', 'r') as fort13:
shutil.copyfileobj(com, outFile)
with open('command.info', 'r') as com:
shutil.copyfileobj(fort13, outFile)
这不会跳过空行,但猫也不会这样做,所以我不确定你真的想要。
对于这样的事情, 列表理解是很棒的:
with open('command.fort.13', 'w') as output:
for f in ['fort.13', 'command.info']:
output.write(''.join([line for line in open(f).readlines() if line.strip()]))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.