我需要知道如何从python中的文件中读取行,以便我先读取最后一行,然后以这种方式继续,直到光标到达文件的开头.有任何想法吗?
如何实现python中的'head'和'tail'命令以及文本文件的行后向读取?
我们有几个应用服务器和一个中央监控服务器.
我们目前正在从监控服务器运行带有"tail -f"的ssh,以便从应用服务器实时流式传输多个文本日志文件.
除了整个方法的脆弱性之外,问题在于杀死ssh进程有时会使僵尸尾部进程落后.我们使用-t来创建伪终端,但它仍然有时会留下僵尸进程,而且-t显然也会导致我们正在使用的作业调度产品出现问题.
作为一个廉价而肮脏的解决方案,直到我们能够获得正确的集中式日志记录(Logstash和RabbitMQ,希望如此),我希望编写一个简单的Python包装器,它将启动ssh和"tail -f",仍然捕获输出,但是将PID存储到磁盘上的文本文件中,以便我们可以在以后根据需要终止相应的尾部进程.
我最初尝试使用subprocess.Popen,但后来实际上实时获取"tail -f"输出问题(然后需要重定向到文件) - 显然会有一些阻塞/缓冲问题.
一些消息来源似乎建议使用pexpect,或pxssh或类似的东西.理想情况下,我只想使用Python,如果可能的话,它包含了库 - 但是,如果库真的是唯一的方法,那么我对此持开放态度.
有没有一个简单的方法让Python用"tail -f"启动ssh,实时将输出打印到本地STDOUT(这样我可以重定向到本地文件),并将PID保存到文件中杀了以后?或者即使我不使用ssh with tail -f,仍然可以在(近)实时流式传输远程文件,包括将PID保存到文件中?
干杯,维克多
编辑:只是为了澄清 - 我们希望在我们终止SSH进程时尾部进程死亡.
我们想从监控服务器启动ssh和"tail -f",然后在我们Ctlr-C那时,远程盒子上的尾部进程也应该死掉 - 我们不希望它留下来.通常使用-t的ssh应该修复它,但由于我不理解的原因,它不完全可靠,并且它不能很好地与我们的作业调度一起使用.
因此,使用屏幕来保持进程的另一端不是我们想要的.
我想循环一个迭代器的"切片".我不确定这是否可行,因为我知道切片迭代器是不可能的.我想做的是:
def f():
for i in range(100):
yield(i)
x = f()
for i in x[95:]:
print(i)
Run Code Online (Sandbox Code Playgroud)
这当然失败了:
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-37-15f166d16ed2> in <module>()
4 x = f()
5
----> 6 for i in x[95:]:
7 print(i)
TypeError: 'generator' object is not subscriptable
Run Code Online (Sandbox Code Playgroud)
是否有一种pythonic方式来循环生成器的"切片"?
基本上我实际关注的生成器读取一个非常大的文件并逐行执行一些操作.我想测试文件的切片以确保事情按预期执行,但让它在整个文件上运行是非常耗时的.
编辑:
如上所述,我需要在一个文件上.我希望有一种方法可以使用生成器显式指定这个例子:
import skbio
f = 'seqs.fna'
seqs = skbio.io.read(f, format='fasta')
Run Code Online (Sandbox Code Playgroud)
seqs是一个生成器对象
for seq in itertools.islice(seqs, 30516420, 30516432):
#do a bunch of stuff here
pass
Run Code Online (Sandbox Code Playgroud)
上面的代码做了我需要的,但是仍然非常慢,因为生成器仍然遍历所有行.我希望只遍历指定的切片
我为一些Java应用程序执行性能测试.应用程序在测试期间会生成非常大的日志文件(可能是7-10 GB).我需要在特定日期和时间之间修剪这些日志文件.目前,我使用python脚本,它解析datetime python对象中的日志时间戳并仅打印匹配的字符串.但这个解决方案非常缓慢.解析5 GB日志大约25分钟显然日志文件中的条目是顺序的,我不需要逐行读取所有文件.我考虑从开始和结束读取文件,直到条件匹配并在匹配的行数之间打印文件.但我不知道如何从后面读取文件,而不将其下载到内存中.
拜托,您能为我推荐一些针对此案例的套装解决方案.
这是python脚本的一部分:
lfmt = '%Y-%m-%d %H:%M:%S'
file = open(filename, 'rU')
normal_line = ''
for line in file:
if line[0] == '[':
ltimestamp = datetime.strptime(line[1:20], lfmt)
if ltimestamp >= str and ltimestamp <= end:
normal_line = 'True'
else:
normal_line = ''
if normal_line:
print line,
Run Code Online (Sandbox Code Playgroud) 许多文本编码都具有以下属性:您可以向后查看编码文本,但仍然可以对其进行解码.ASCII,UTF-8,UTF-16和UTF-32都具有此属性.这可以让你做一些方便的事情,比如读取文件的最后一行而不读取它前面的所有行,或者从文件中的当前位置向后移几行.
不幸的是,Python似乎没有任何方法可以向后解码文件.您不能read向后或seek按编码文件中的字符数量.codecs模块中的解码器支持向前递增解码,但不支持向后解码.似乎没有任何"UTF-8-backwardwards"编解码器,我可以以相反的顺序提供UTF-8字节.
我本可以自己实现与编解码器相关的字符边界同步,向后读取二进制块,并将正确对齐的块提供给codecs模块中的适当解码器,但这听起来像非专家会错过一些细微的细节和没有注意到输出是错误的.
有没有简单的方法可以使用现有工具在Python中向后解码文本?
有几个人似乎错过了阅读整个文件来做到这一点的观点.虽然我在澄清事情,但我还是补充一点,这也需要适用于可变长度编码.UTF-8支持是必须的.
文件看起来像这样:
abcd
efgh
ijkl
我想使用C它来读取文件,以便它首先读取最后一行:
ijkl
efgh
abcd
我似乎无法找到不使用array存储的解决方案.请帮忙.
edit0: 谢谢你的所有答案.只是为了让你知道,我是创建这个文件的人.那么,我可以以相反的顺序创建它吗?那可能吗?
我有30个文本文件,每个30行.出于某种原因,我需要编写一个打开文件1的脚本,打印文件1的第1行,关闭它,打开文件2,打印文件2的第2行,关闭它,依此类推.我试过这个:
import glob
files = glob.glob('/Users/path/to/*/files.txt')
for file in files:
i = 0
while i < 30:
with open(file,'r') as f:
for index, line in enumerate(f):
if index == i:
print(line)
i += 1
f.close()
continue
Run Code Online (Sandbox Code Playgroud)
显然,我收到以下错误:
ValueError:关闭文件的I/O操作.
因为f.close()的事情.如何只读取所需的行后,如何从文件移动到下一个文件?
我有两个要求.
第一个要求 - 我想读取文件的最后一行,并将最后一个值赋给python中的变量.
第二要求 -
这是我的示例文件.
<serviceNameame="demo" wsdlUrl="demo.wsdl" serviceName="demo"/>
<context:property-placeholder location="filename.txt"/>
Run Code Online (Sandbox Code Playgroud)
从这个文件我想读取内容,即filename.txt将在之后<context:property-placeholder location= ..并希望将该值赋给python中的变量.
我在目录中有一些txt文件,我需要从所有这些文件中获取最后15行.我怎么能用python做到这一点?
我选择了这段代码:
from os import listdir
from os.path import isfile, join
dir_path= './'
files = [ f for f in listdir(dir_path) if isfile(join(dir_path,f)) ]
out = []
for file in files:
filedata = open(join(dir_path, file), "r").readlines()[-15:]
out.append(filedata)
f = open(r'./fin.txt','w')
f.writelines(out)
f.close()
Run Code Online (Sandbox Code Playgroud)
但我收到错误"TypeError:writelines()参数必须是一个字符串序列".我认为这是因为俄罗斯的字母.
我是编程和Python的新手.
我编写了一个实现unix尾部的函数:
def tail(file):
strin = open(file, 'r')
lis = strin.readlines()
lastline = lis[-1]
return lastline
strin.close()
Run Code Online (Sandbox Code Playgroud)
但我认为它在性能上并不是最佳的.
我该如何改进?
我正在创建一个过夜构建的电子邮件响应,我想从结果文件中获取最后50行并将其放入摘要文件中.我所做的代码如下,任何人都可以帮忙吗?
def email_success():
fp = open(results_file, 'r')
sum_file = (fp.readlines()[-50:])
fp.close()
myfile = open(result_summary,'w')
myfile.write(sum_file)
myfile.close()
Run Code Online (Sandbox Code Playgroud)
我在尝试此代码时收到以下错误消息:
Traceback (most recent call last):
File "email_success.py", line 76, in <module>
if __name__ == '__main__': myObject = email_success()
File "email_success.py", line 45, in email_success
myfile = open(result_summary,'w')
TypeError: coercing to Unicode: need string or buffer, tuple found
Run Code Online (Sandbox Code Playgroud)
谢谢
结果摘要是存储地址的变量.
result_summary = (t, 'results_summary.txt')
Run Code Online (Sandbox Code Playgroud)
抱歉犯了一个愚蠢的错误,我忘了添加os.path.join
result_summary = os.path.join(t, 'results_summary.txt')
Run Code Online (Sandbox Code Playgroud)
谢谢您的帮助
@alok这是一个目录地址,我忘了添加os.join使其成为一个字符串.这是造成错误的原因
我需要更新一些超过2GB文件的最后一行,这些文件由无法读取的文本行组成readlines().目前,它通过逐行循环工作正常.但是,我想知道是否有任何编译库可以更有效地实现这一点?谢谢!
myfile = open("large.XML")
for line in myfile:
do_something()
Run Code Online (Sandbox Code Playgroud)