可以通过子进程执行.awk文件吗?

2 投票
3 回答
63 浏览
提问于 2025-04-14 17:34

我有三个文件,都在同一个文件夹里:

  • ex.awk
  • data.csv
  • file.py

我想用一个叫做 subprocess 的工具来运行我的 awk 文件,这样我将来可以在 PyTest 的测试用例中调用它。这是我的示例文件:

ex.awk

#!/usr/bin/awk -f

BEGIN {
    FS = ",";
}
{
    print NF;
}
END {print "DONE"}

data.csv

10,34,32
4,76,8304
4759,5869,2940

file.py

import subprocess
cmd = ['awk', '-f', 'ex.awk', 'data.csv']
subprocess.run(cmd)

在 bash 里,下面这个命令可以正常工作:

$ awk -f ex.awk data.csv
3
3
3
DONE

我想在运行 file.py 的时候得到同样的结果,但我遇到了以下错误:

FileNotFoundError: [WinError 2] 系统找不到指定的文件

我是不是在我的参数数组里漏掉了什么?我需要使用其他的 subprocess 参数,比如 shell 或者其他的吗?

3 个回答

1

你现在的代码应该是可以工作的;错误提示看起来是你的 PATH 出了点问题。

不过,你的 Awk 脚本其实可以很简单地用 Python 来实现。

import csv

with open("data.csv") as inp:
    reader = csv.reader(inp)
    for row in reader:
        print(len(row))
# I would omit this
print("DONE")

Python 的 csv 模块在处理带引号的字段等方面更强大;如果你需要 Awk 那种简单的处理方式,其实用 Python 也更简单。

with open("data.csv") as inp:
    for row in inp:
        print(len(row.split(",")))

Awk 和 sed 脚本在命令行中使用时很有意义;它们是命令行环境的一部分。当你在写 Python 代码时,通常用 Python 完整地写一个脚本会更合理。

1

显然,Python找不到你在环境变量中指定的awk,这个环境变量叫$PATH(在Windows上是%path%)。这意味着你的bash和Python看到的可执行文件目录列表不一样!

所以,你需要解决这个问题——看起来这是在Windows上,我很遗憾不能告诉你如何在这个特定的操作系统上调整环境变量。

总的来说,你的awk脚本写得不太好,处理包含,的字符串时要小心,特别是当它们被转义或者放在引号里的时候。而且,Python有一个功能强大的csv模块,可能能很轻松地完成你在awk中做的事情。把awk加进来似乎有点多余!

1

在Windows上从Python执行awk脚本时,如果遇到FileNotFoundError错误,通常是因为Windows处理文件路径的方式不同,或者是一些Unix/Linux专用的工具在Windows命令提示符下无法直接使用。因此,你需要提供文件的绝对路径,或者更新环境变量路径,以确保它可以被找到。

在调整好'C:/Program Files/Git/usr/bin/awk.exe'的路径后,可以尝试以下方法:

import subprocess

cmd = ['C:/Program Files/Git/usr/bin/awk.exe', '-f', 'ex.awk', 'data.csv'] 
subprocess.run(cmd, shell=True)

另外,你也可以在Git Bash或WSL提供的类Unix环境中执行它:

import subprocess

cmd = 'awk -f ex.awk data.csv'
subprocess.run(cmd, shell=True, executable='C:/Program Files/Git/bin/bash.exe')

撰写回答