簡體   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