繁体   English   中英

在python子进程popen中格式化命令

[英]Formatting a command in python subprocess popen

我正在尝试格式化以下awk命令

awk -v OFS="\t" '{printf "chr%s\t%s\t%s\n", $1, $2-1, $2}' file1.txt > file2.txt

用于python子进程popen。 但是我很难格式化它。 我已经尝试了类似答案中提出的解决方案,但是没有一个起作用。 我也尝试过使用原始字符串文字。 我也不想使用shell = True,因为这是不推荐的

根据评论进行编辑:我尝试过的命令是

awk_command = """awk -v OFS="\t" '{printf "chr%s\t%s\t%s\n", $1, $2-1, $2}' file1.txt > file2.txt"""
command_execute = Popen(shlex.split(awk_command))

但是执行此操作时出现以下错误

KeyError: 'printf "chr%s\t%s\t%s\n", $1, $2-1, $2'

谷歌搜索错误表明,当为一个未定义的键请求一个值,但我不了解其上下文时,会发生这种情况

>是Shell重定向运算符。 要在Python中实现它,请使用stdout参数:

#!/usr/bin/env python
import shlex
import subprocess

cmd = r"""awk -v OFS="\t" '{printf "chr%s\t%s\t%s\n", $1, $2-1, $2}'"""
with open('file2.txt', 'wb', 0) as output_file:
    subprocess.check_call(shlex.split(cmd) + ["file1.txt"], stdout=output_file)

为了避免启动单独的过程,您可以在纯Python中实现此特定的awk命令。

  1. 最简单的方法(尤其是如果您希望保留输出重定向的东西)是使用带有shell=True subprocess -那么您只需要转义Python特殊字符。 整体而言,该行将由默认外壳程序解释。

    • 警告:请勿在不先消毒的情况下将其用于不受信任的输入!
  2. 或者,您可以将命令行替换为argv -type序列,然后将其提供给subprocess 然后,您需要提供程序将看到的内容:

    • 删除所有外壳程序级转义
    • 删除输出重定向的东西,而是自己进行重定向

关于具体问题:

  • 您没有在字符串中转义Python特殊字符,因此\\t\\n成为了文字标签和换行符(尝试print awk_command
  • 使用shlex.splitshell=True没什么不同-额外增加了可靠性,因为它不能保证在每种情况下是否都可以以与shell相同的方式解析字符串(更不用说shell缺少转换了)。

    • 具体来说,它不知道或不在乎重定向部分的特殊含义:

       >>> awk_command = """awk -v OFS="\\\\t" '{printf "chr%s\\\\t%s\\\\t%s\\\\n", $1, $2- 1, $2}' file1.txt > file2.txt""" >>> shlex.split(awk_command) ['awk','-v','OFS=\\\\t','{printf "chr%s\\\\t%s\\\\t%s\\\\n", $1, $2-1, $2}','file1.txt','>','file2.txt'] 

因此,如果您希望使用shell=False ,请自己构造参数列表。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM