Estoy tratando de formatear el siguiente comando awk
awk -v OFS="\t" '{printf "chr%s\t%s\t%s\n", $1, $2-1, $2}' file1.txt > file2.txt
para uso en python subprocess popen. Sin embargo estoy teniendo dificultades para formatearlo. He intentado soluciones sugeridas en respuestas similares pero ninguna de ellas funcionó. También he intentado usar literales de cadena en bruto. Además, no me gustaría usar shell = True, ya que no se recomienda
Editar de acuerdo con el comentario: El comando que probé fue
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))
Sin embargo me sale el siguiente error al ejecutar este
KeyError: 'printf "chr%s\t%s\t%s\n", $1, $2-1, $2'
buscar en Google el error sugiere que esto suceda cuando se solicita un valor para una clave no definida pero no entiendo su contexto aquí
El método más simple, especialmente si desea mantener las cosas de redireccionamiento de salida, es usar el subprocess
con shell=True
– entonces solo necesita escapar de los caracteres especiales de Python. La línea, en su totalidad, será interpretada por el shell predeterminado.
Alternativamente, puede reemplazar la línea de comando con una secuencia de tipo argv
y enviarla al subprocess
. Entonces, necesitas proporcionar cosas como el progtwig lo vería:
Respecto a los problemas específicos:
\t
y \n
convirtieron en la pestaña literal y la nueva línea (intenta print awk_command
) el uso de shlex.split
no es diferente de shell=True
– con una falta de fiabilidad agregada, ya que no puede garantizar si se analizaría la cadena de la misma manera que lo haría su shell en todos los casos (sin mencionar la falta de transmutaciones que hace la shell).
Específicamente, no sabe ni se preocupa por el significado especial de la parte de redirección:
>>> 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']
Por lo tanto, si desea usar shell=False
, construya la lista de argumentos usted mismo.
>
es el operador de redirección de shell. Para implementarlo en Python, use el parámetro 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)
Para evitar iniciar un proceso separado, puede implementar este comando awk
en particular en Python puro.