从Python调用awk
我想从Python里调用一个awk命令行脚本:
os.system('''awk 'BEGIN{FS="\t";OFS="\n"} {a[$1]=a[$1] OFS $2 FS $3 FS $4} END{for (i in a) {print i a[i]}}' 2_lcsorted.txt > 2_locus_2.txt''')
结果出现了以下错误:
awk: cmd. line:1: BEGIN{FS=" ";OFS="
awk: cmd. line:1: ^ unterminated string
awk: cmd. line:1: BEGIN{FS=" ";OFS="
awk: cmd. line:1: ^ syntax error
256
当我使用subprocess,特别是subprocess.call的时候,又出现了另一种错误:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib64/python2.7/subprocess.py", line 493, in call
return Popen(*popenargs, **kwargs).wait()
File "/usr/lib64/python2.7/subprocess.py", line 679, in __init__
errread, errwrite)
File "/usr/lib64/python2.7/subprocess.py", line 1249, in _execute_child
raise child_exception
OSError: [Errno 2] No such file or directory
在命令行里运行是没问题的,我只是想把所有步骤合并到一个Python脚本里,而且因为某些明显的原因,awk在处理某些步骤时更好用。有人能帮我解释一下这些错误的原因吗?
2 个回答
1
你不想让Python把\n
转换成换行符(或者把\t
转换成制表符),再把这个字符串传给system
。可以像jwpat7建议的那样,使用r"""...."""
。另外一种方法是可以在字符串里写成... OFS="\\n" ...
。
0
补充一下,你可能更适合使用 PyAwk:pyawk.sourceforge.net。还有,如果你在用 subprocess 的话,问题在于你的命令应该被拆分开来。其实,subprocess 的工作方式和 os.system 有点不同。subprocess 要求命令是一个字符串,而不是一个列表。例如,
`os.system('''awk 'BEGIN {FS="\t";OFS="\n"} {a[$1]=a[$1] OFS $2 FS $3 FS $4}
END {for (i in a) {print i a[i]}}' 2_lcsorted.txt > 2_locus_2.txt''')`
不应该是
`subprocess.call('''awk 'BEGIN {FS="\t";OFS="\n"} {a[$1]=a[$1] OFS $2 FS $3 FS $4}
END {for (i in a) {print i a[i]}}' 2_lcsorted.txt > 2_locus_2.txt''')`
这样是行不通的。如果你给 subprocess 一个字符串,它会认为这是你想执行的命令的路径。命令需要是一个列表。可以看看 www.gossamer-threads.com/lists/python/python/724330。还有,因为你在使用文件重定向,所以你应该使用
`subprocess.call(cmd, shell=True)`