我试图使用pythonscrip中的shell命令打印目录中每个文件的最后一行

2024-04-25 14:13:14 发布

您现在位置:Python中文网/ 问答频道 /正文

我将一个目录中的文件数量存储在变量中,并将它们的名称存储在数组中。我无法在数组中存储文件名。 这是我写的代码。在

import os
temp = os.system('ls -l /home/demo/ | wc -l')

no_of_files = temp - 1

command = "ls -l /home/demo/ | awk 'NR>1 {print $9}'"

file_list=[os.system(command)]

for i in range(len(file_list))
    os.system('tail -1 file_list[i]')

Tags: 文件目录名称home数量osdemo文件名
3条回答

你的shell脚本太复杂了。在

output = subprocess.check_output('tail -qn1 *', shell=True)

或者如果你真的喜欢

^{pr2}$

但是,它不能捕获Python变量中的输出。在

如果您有一个足够新的Python,那么应该使用subprocess.run()。您还可以轻松地让Python对文件进行枚举,以避免令人讨厌的shell=True

output = subprocess.check_output(['tail', '-qn1'] + os.listdir('.'))

如上所述,如果您真的只想将输出打印到屏幕上,而不是Python所能使用的,那么您当然可以使用os.system(),尽管即使在{}文档中也推荐使用{},因为它更通用,启动效率更高(如果使用正确的话)。如果您真的坚持每个文件运行一个tail进程(可能是因为您的tail不支持-q选项?)当然,你也可以这样做:

for filename in os.listdir('.'):
    os.system("tail -n 1 '%s'" % filename)

如果您的文件名包含一个单引号,这仍将无法正常工作。有一些解决方法,但是避免使用shell是非常可取的(所以回到没有shell=Truesubprocess,正确处理转义shell元字符的问题就消失了,因为没有可以从中逃逸元字符的shell)。在

for filename in os.listdir('.'):
    print(subprocess.check_output(['tail', '-n1', filename]))

最后,tail并没有特别做Python本身不容易完成的事情。在

for filename in os.listdir('.'):
    with open (filename, 'r') as handle:
        for line in handle:
            pass
        # print the last one only
        print(line.rstrip('\r\n'))

如果您知道预期的行长度并且文件很大,那么可能是seek到文件末尾附近的某个地方,尽管很明显,您需要知道从结尾到搜索的距离有多远,以便能够读取每个文件中的最后一行。在

您可以使用一个没有太大问题的循环:

files = [f for f in os.listdir('.') if os.path.isfile(f)]

for f in files:
    with open(f, 'rb') as fh:
        last = fh.readlines()[-1].decode()
        print('file: {0}\n{1}\n'.format(f, last))
    fh.close()

输出

^{pr2}$

{cd1>可能是你最好的选择。也许用tail代替:

for f in files:
    print('file: {0}'.format(f))
    subprocess.check_call(['tail', '-n', '1', f])
    print('\n')

解码是可选的,尽管对于文本“utf-8”通常有效,或者如果它是二进制/text/etc的组合,那么“iso-8859-1”之类的东西通常应该起作用。在

os.system返回命令的exitcode,而不是输出。尝试使用subprocess.check_outputshell=True

示例:

>>> a = subprocess.check_output("ls -l /home/demo/ | awk 'NR>1 {print $9}'", shell=True)
>>> a.decode("utf-8").split("\n")

编辑(如@tripleee建议)你可能不想这样做,因为它会变得疯狂。Python在这方面有很好的功能。例如:

^{pr2}$

将直接为您提供该文件夹中的文件和文件夹列表。一旦你有了这个,你就可以做len(names)来获得第一个命令。在

另一个选择是:

>>> import os
>>> os.listdir("/home/demo")

在这里,glob将给出整个文件路径/home/demo/file.txt,而{}只给你文件名file.txt

ls -l /home/demo/ | wc -l命令也不是正确的值,因为ls -l将在顶部显示“totalx”,指出它找到的文件总数和其他信息。在

相关问题 更多 >