Python调用Shell命令:打印目录文件末行及文件数组存储问题
解决Python处理目录文件的两个常见问题
咱们先拆解你遇到的两个问题,一步步给出修复方案和更优实现:
问题1:打印目录下每个文件的最后一行
这里提供两种实现方式,你可以根据场景选择:
方式1:调用Shell的tail命令(适合熟悉Shell的场景)
注意别再用os.system了——它只返回命令的退出状态码,拿不到命令输出。改用subprocess模块来捕获结果:
import subprocess import os target_dir = "/home/demo" # 遍历目录下的所有文件(跳过子目录) for filename in os.listdir(target_dir): file_path = os.path.join(target_dir, filename) if os.path.isfile(file_path): # 调用tail命令获取最后一行 last_line = subprocess.check_output(["tail", "-1", file_path], text=True).strip() print(f"{filename} 的最后一行:{last_line}")
方式2:纯Python实现(更可靠,无Shell依赖)
不需要依赖Shell命令,直接用Python读取文件最后一行,能完美处理含空格、特殊字符的文件名:
import os target_dir = "/home/demo" def get_last_line(file_path): with open(file_path, "rb") as f: # 从文件末尾反向读取,高效处理大文件 try: f.seek(-2, os.SEEK_END) while f.read(1) != b'\n': f.seek(-2, os.SEEK_CUR) except OSError: # 文件只有一行或为空时直接回到开头 f.seek(0) return f.readline().decode().strip() for filename in os.listdir(target_dir): file_path = os.path.join(target_dir, filename) if os.path.isfile(file_path): last_line = get_last_line(file_path) print(f"{filename} 的最后一行:{last_line}")
问题2:获取文件数量和文件名数组(修复你的代码)
你的原代码核心问题是误用了os.system——它返回的是命令退出状态码(0表示成功),不是命令的输出内容。下面给出两种修复方案:
方式1:修复Shell命令调用的写法
如果坚持用Shell命令,用subprocess捕获输出:
import subprocess import os target_dir = "/home/demo" # 获取文件数量(减去ls -l的表头行) count_output = subprocess.check_output(f"ls -l {target_dir} | wc -l", shell=True, text=True) no_of_files = int(count_output.strip()) - 1 # 获取文件名列表 files_output = subprocess.check_output(f"ls -l {target_dir} | awk 'NR>1 {{print $9}}'", shell=True, text=True) file_list = files_output.strip().split('\n') # 验证结果并打印每个文件最后一行 print(f"文件数量:{no_of_files}") print(f"文件名列表:{file_list}") for file in file_list: file_path = os.path.join(target_dir, file) if os.path.isfile(file_path): subprocess.run(["tail", "-1", file_path], text=True)
⚠️ 注意:这种方式如果目录或文件名含空格、特殊字符(比如&、*)会出错,且存在安全风险,更推荐下面的纯Python方式。
方式2:纯Python实现(推荐,安全且可靠)
完全不需要Shell命令,直接用Python内置模块处理:
import os target_dir = "/home/demo" # 获取目录下所有文件(自动跳过子目录) file_list = [f for f in os.listdir(target_dir) if os.path.isfile(os.path.join(target_dir, f))] no_of_files = len(file_list) # 验证结果 print(f"文件数量:{no_of_files}") print(f"文件名列表:{file_list}") # 打印每个文件最后一行 for filename in file_list: file_path = os.path.join(target_dir, filename) with open(file_path, 'r') as f: lines = f.readlines() if lines: print(f"{filename} 的最后一行:{lines[-1].strip()}") else: print(f"{filename} 是空文件")
这种方式不仅避免了Shell命令的各种坑,代码也更易维护,还能兼容各种特殊文件名。
内容的提问来源于stack exchange,提问作者Prashant Luhar
相关产品推荐
相关产品推荐

