Python plumbum: Passing $ in an cmd argument

325 Views Asked by At

I am trying to execute the following command in python using plumbum:

sort -u -f -t$'\t' -k1,1 file1 > file2

However, I am having issues passing the -t$'\t' argument. Here is my code:

from plumbum.cmd import sort
separator = r"-t$'\t'"
print separator
cmd = (sort["-u", "-f", separator, "-k1,1", "file1"]) > "file2"
print cmd
print cmd()

I can see problems right away after print separator and print cmd() executes:

-t$'\t'
/usr/bin/sort -u -f "-t\$'\\t'" -k1,1 file1 > file2
  1. The argument is wrapped in double quotes.
  2. An extra \ before $ and \t is inserted.

How should I pass this argument to plumbum?

1

There are 1 best solutions below

4
On BEST ANSWER

You may have stumbled into limitations of the command line escaping.

I could make it work using subprocess module, passing a real tabulation char litteraly:

import subprocess

p=subprocess.Popen(["sort","-u","-f","-t\t","-k1,1","file1",">","file2"],shell=True)
p.wait()

Also, full python short solution that does what you want:

with open("file1") as fr, open("file2","w") as fw:
    fw.writelines(sorted(set(fr),key=lambda x : x.split("\t")[0]))

The full python solution doesn't work exactly the same way sort does when dealing with unicity. If 2 lines have the same first field but not the same second field, sort keeps one of them, whereas the set will keep both.

EDIT: unchecked but you just confirmed that it works: just tweak your plumbum code with:

separator = "-t\t"

could just work, although out of the 3 ones, I'd recommend the full python solution since it doesn't involve an external process and therefore is more pythonic and portable.