将Bash脚本转为Python时,调用jq/awk命令持续触发类型错误求助
解决subprocess调用jq的类型错误及代码修正
先梳理你代码里的核心问题,逐个修正:
代码里的错误点
- 变量与文件操作错误
filename = temp.csv没加引号,Python会把temp.csv当成变量,得写成filename = "temp.csv"。- 第二个
with open(ndfile, 'a')缺冒号,而且没把打开的文件存成变量,直接遍历字符串ndfile会逐个读字符,不是文件行。应该改成读取模式打开account.csv,比如with open(ndfile, 'r') as account_file:。
- subprocess调用jq的关键错误
- subprocess传命令必须拆成列表元素,不能把整个jq命令当一个字符串(除非开
shell=True,不推荐)。正确的参数列表是["jq", "-r", '.accountdata[] | [.id, .name, .number, .date] | @csv'],另外jq里的字段要加.,比如.id,不然jq会把id当成变量,不是JSON字段,这就是你触发类型错误的核心原因。 - 原始代码里jq没输入源,会一直等输入,得把每行的JSON内容通过
input参数传给jq。
- subprocess传命令必须拆成列表元素,不能把整个jq命令当一个字符串(除非开
- 其他逻辑错误
result.write(line)完全错了,subprocess.run返回的是CompletedProcess对象,根本没有write方法。- 后面awk命令用了
file_name(文件句柄),不是文件名filename,会报错。
修正后的代码
import subprocess filename = "temp.csv" ndfile = "account.csv" # 读取account.csv每行JSON,用jq提取字段转CSV后追加到temp.csv with open(filename, 'a') as temp_file: with open(ndfile, 'r') as account_file: for line in account_file: line = line.strip() if not line: continue # 跳过空行 # 调用jq处理当前行JSON,输出直接写入temp.csv subprocess.run( ["jq", "-r", '.accountdata[] | [.id, .name, .number, .date] | @csv'], input=line.encode('utf-8'), stdout=temp_file, stderr=subprocess.PIPE, check=True ) # 用awk对temp.csv按第一列去重,结果覆盖写回account.csv subprocess.run( ['awk', '-F', ',', '!seen[$1]++', filename], stdout=open(ndfile, 'w'), check=True )
修正说明
- 给文件名加引号,正确打开文件并遍历行;
- 拆分jq命令参数,修正字段表达式,通过
input传每行JSON,解决jq的类型错误; - 去掉错误的
write调用,直接让subprocess输出写入文件; - 加
check=True让命令执行失败时抛出异常,方便调试;stderr=subprocess.PIPE可以捕获jq的错误信息,排查问题; - awk命令改用文件名,正确覆盖写入account.csv。
内容的提问来源于stack exchange,提问作者Jordan Mersha
相关产品推荐
相关产品推荐

