使用subprocess.call从Python内部调用awk的问题



从Python内部调用awk有一些问题。通常,我会执行以下操作从命令行调用awk中的命令。

  1. 打开命令行,无论是否在管理模式下
  2. 将我的目录改为awk.exe,即cd RGnuWin32bin
  3. 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/')

最新更新