从Python内部调用awk有一些问题。通常,我会执行以下操作从命令行调用awk中的命令。
- 打开命令行,无论是否在管理模式下
- 将我的目录改为
awk.exe
,即cd RGnuWin32bin
- Call
awk -F "," "{ print > ("split-" $10 ".csv") }" large.csv
我的命令用于将基于第10列的large.csv
文件拆分为多个名为split-[COL VAL HERE].csv
的文件。运行这个命令没有问题。我试图使用subprocess.call()
在Python中运行相同的代码,但我遇到了一些问题。我运行以下代码:
def split_ByInputColumn():
subprocess.call(['C:/R/GnuWin32/bin/awk.exe', '-F', '","',
'"{ print > (\"split-\" $10 \".csv\") }"', 'large.csv'],
cwd = 'C:/R/GnuWin32/bin/')
,显然,当我执行函数(CPU使用率等)时,有些东西正在运行,但是当我去检查C:/R/GnuWin32/bin/
时,目录中没有拆分文件。知道哪里出了问题吗?
正如我在之前被否决的答案中所述,您过度保护了参数,使awk
参数解析失败。
因为没有注释,我以为是打错了,但它起作用了…所以我想这是因为我应该强烈建议一个完整的python解决方案,这是这里最好的事情(正如我之前的回答所述)
在python中编写等效的代码并不简单,因为我们必须模仿awk打开文件并在文件后面追加内容的方式。但它更集成,更python化,并且在输入文件中出现引号时可以正确处理引号。
我花时间编写了&测试:
def split_ByInputColumn():
# get rid of the old data from previous runs
for f in glob.glob("split-*.csv"):
os.remove(f)
open_files = dict()
with open('large.csv') as f:
cr = csv.reader(f,delimiter=',')
for r in cr:
tenth_row = r[9]
filename = "split-{}.csv".format(tenth_row)
if not filename in open_files:
handle = open(filename,"wb")
open_files[filename] = (handle,csv.writer(handle,delimiter=','))
open_files[filename][1].writerow(r)
for f,_ in open_files.values():
f.close()
split_ByInputColumn()
在细节:- 读取大文件为csv(优点:引用处理得当)
- 计算目标文件名
- 如果文件名不在字典中,打开它并创建
csv.writer
对象 - 将行写入相应的字典
- 最后,关闭文件句柄
awk
:
import subprocess
def split_ByInputColumn():
subprocess.call(['awk.exe', '-F', ',',
'{ print > ("split-" $10 ".csv") }', 'large.csv'],cwd = 'some_directory')
其他人贴了一个答案(然后删除了它),但问题是我过度保护了我的论点。下面的代码可以工作:
def split_ByInputColumn():
subprocess.call(['C:/R/GnuWin32/bin/awk.exe', '-F', ',',
'{ print > ("split-" $10 ".csv") }', 'large.csv'],
cwd = 'C:/R/GnuWin32/bin/')