Python调用Shell执行SQL:将输出转为可行列访问的列表
处理Shell脚本SQL输出为结构化列表的方案
我明白你现在的处境——生产环境没法用cx_Oracle,只能靠调用Shell脚本执行SQL,现在拿到的输出是一大串字符串,得把它转成能按行列访问的列表,还要过滤掉前两行的提示信息,对吧?没问题,咱们一步步来解决:
核心思路
我们需要把输出字符串拆解成行列表,过滤掉无关的提示行,再把每一行拆成列列表,这样就能像操作二维数组一样访问指定列了。这里只用到你允许的subprocess.Popen或commands.getoutput方法,完全符合要求。
方案一:使用subprocess.Popen
import subprocess import re # 调用Shell脚本并获取输出(Python3中需要decode转成字符串) output = subprocess.Popen( ["sh", "ABC.sh"], stdout=subprocess.PIPE ).communicate()[0].decode('utf-8') # 1. 把输出按行分割,跳过前两行提示信息 sql_result_lines = output.splitlines()[2:] # 2. 处理每一行:用正则分割任意数量的空格,得到列列表 structured_data = [] for line in sql_result_lines: # 先去掉首尾空白,再用正则分割任意空白字符序列 columns = re.split(r'\s+', line.strip()) structured_data.append(columns) # 3. 按行列访问,比如打印每行的第1、3、5列(Python是0索引,对应0、2、4) for row in structured_data: print(f"对象名称: {row[0]}, 版本号: {row[2]}, 状态标识: {row[4]}")
方案二:使用commands.getoutput
如果习惯用commands模块,代码会更简洁,因为它直接返回字符串:
import commands import re # 调用Shell脚本获取输出 output = commands.getoutput("sh ABC.sh") # 同样跳过前两行,再处理每行的列 sql_result_lines = output.splitlines()[2:] structured_data = [re.split(r'\s+', line.strip()) for line in sql_result_lines] # 示例:遍历打印指定列 for row in structured_data: print(f"{row[0]} | {row[2]} | {row[4]}")
关键细节说明
splitlines():比直接用split('\n')更可靠,它能自动处理不同操作系统的换行符(比如\r\n或\n)。- 正则
re.split(r'\s+'):SQL查询结果的列之间通常是多个空格分隔,用这个可以把任意数量的空白字符作为分隔符,避免分割出空字符串。 - 索引注意:Python是0起始索引,所以你要的第1、3、5列对应索引
0、2、4。
内容的提问来源于stack exchange,提问作者LOrD_ARaGOrN
相关产品推荐
相关产品推荐

