我试图使用python脚本中的shell命令打印目录中每个文件的最后一行
我将目录中的文件数存储在变量中,并将其名称存储在数组中。我无法在数组中存储文件名。 这是我写的一段代码我试图使用python脚本中的shell命令打印目录中每个文件的最后一行,python,shell,Python,Shell,我将目录中的文件数存储在变量中,并将其名称存储在数组中。我无法在数组中存储文件名。 这是我写的一段代码 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_lis
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]')
无法存储文件名,因为
os.system
无法按预期返回输出。有关更多信息,请参阅:。从 在Unix上,返回值是以为wait()指定的格式编码的进程的退出状态。请注意,POSIX没有指定C system()函数返回值的含义,因此Python函数的返回值依赖于系统 在Windows上,返回值是系统外壳在运行命令后返回的值,由Windows环境变量COMSPEC:On command.com系统(Windows 95、98和ME)给出,该值始终为0;在cmd.exe系统(Windows NT、2000和XP)上,这是命令运行的退出状态;在使用非本机shell的系统上,请参阅shell文档
os.system
按原样执行linux shell命令。要获取这些shell命令的输出,必须使用pythonsubprocess
注意:在您的情况下,您可以使用
glob
模块或os.listdir()
获取文件名:请参见,您无法存储文件名,因为os.system
不会按预期返回输出。有关更多信息,请参阅:。从 在Unix上,返回值是以为wait()指定的格式编码的进程的退出状态。请注意,POSIX没有指定C system()函数返回值的含义,因此Python函数的返回值依赖于系统 在Windows上,返回值是系统外壳在运行命令后返回的值,由Windows环境变量COMSPEC:On command.com系统(Windows 95、98和ME)给出,该值始终为0;在cmd.exe系统(Windows NT、2000和XP)上,这是命令运行的退出状态;在使用非本机shell的系统上,请参阅shell文档
os.system
按原样执行linux shell命令。要获取这些shell命令的输出,必须使用pythonsubprocess
注意:在您的情况下,您可以使用
glob
模块或os.listdir()
:请参阅os.system
返回命令的exitcode,而不是输出。尝试使用子流程。使用shell=True检查输出
例如:
>>> a = subprocess.check_output("ls -l /home/demo/ | awk 'NR>1 {print $9}'", shell=True)
>>> a.decode("utf-8").split("\n")
编辑(正如@tripleee所建议的)你可能不想这样做,因为它会变得疯狂。Python对于这样的事情有很好的功能。例如:
>>> import glob
>>> names = glob.glob("/home/demo/*")
将直接向您提供该文件夹中的文件和文件夹列表。一旦有了这个命令,就可以执行len(names)
来获取第一个命令
另一个选择是:
>>> import os
>>> os.listdir("/home/demo")
在这里,glob将为您提供整个文件路径/home/demo/file.txt
,而os.listdir
将只提供文件名file.txt
ls-l/home/demo/|wc-l
命令的值也不正确,因为ls-l
将在顶部显示“total X”,说明找到的文件总数和其他信息。os.system
返回命令的exitcode,而不是输出。尝试使用子流程。使用shell=True检查输出
例如:
>>> a = subprocess.check_output("ls -l /home/demo/ | awk 'NR>1 {print $9}'", shell=True)
>>> a.decode("utf-8").split("\n")
编辑(正如@tripleee所建议的)你可能不想这样做,因为它会变得疯狂。Python对于这样的事情有很好的功能。例如:
>>> import glob
>>> names = glob.glob("/home/demo/*")
将直接向您提供该文件夹中的文件和文件夹列表。一旦有了这个命令,就可以执行len(names)
来获取第一个命令
另一个选择是:
>>> import os
>>> os.listdir("/home/demo")
在这里,glob将为您提供整个文件路径/home/demo/file.txt
,而os.listdir
将只提供文件名file.txt
ls-l/home/demo/|wc-l
命令的值也不正确,因为ls-l
会在顶部显示“total X”,说明找到的文件总数和其他信息。您的shell脚本太复杂了
output = subprocess.check_output('tail -qn1 *', shell=True)
或者如果你真的喜欢
os.system('tail -qn1 *')
但是,它不会捕获Python变量中的输出
如果您最近有足够多的Python,您将希望改用subprocess.run()
。您还可以轻松地让Python进行文件枚举,以避免令人讨厌的shell=True
:
output = subprocess.check_output(['tail', '-qn1'] + os.listdir('.'))
如上所述,如果您真的只想将输出打印到屏幕上,而Python无法使用,那么您当然可以使用os.system()
,不过即使在os.system()
文档中也建议使用子流程,因为它更通用,启动效率更高(如果使用正确的话). 如果您确实坚持每个文件运行一个tail
进程(可能是因为您的tail
不支持-q
选项?)
for filename in os.listdir('.'):
os.system("tail -n 1 '%s'" % filename)
如果文件名中包含一个引号,则此操作仍将不正确。有一些变通方法,但最好避免使用shell(因此,回到subprocess
而不使用shell=True
,正确处理转义shell元字符的问题就消失了,因为没有可以转义元字符的shell)
最后,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
搜索到文件末尾附近的某个位置,不过显然您需要知道要搜索的距离,以便能够读取每个文件中的最后一行。您的shell脚本太复杂了
output = subprocess.check_output('tail -qn1 *', shell=True)