1

My python script requires an argument of type str.

I am using the ArgumentParser class from argparse.

I want to pass in a string containing a "$" char in the middle, e.g. "file$102_a.txt", but when passed to the script the argument is stored as "file" cutting off the $102_a.

Is there any way to enable argparse to do accomodate this?

Running macOS, python v3.7.6

Thank you for your help.

wjandrea
  • 28,235
  • 9
  • 60
  • 81
amc007
  • 129
  • 7
  • 4
    How are you running the script? It's probably your shell doing that, not anything in Python. Are you sure the argument is stored as `"file"` and not `"file.txt"`? – wjandrea Sep 21 '21 at 16:45
  • 1
    The shell should actually only expand `$1` to the empty string; `102_a` is not a valid identifier, and multi-digit positional parameters require braces to delimit the name, i.e., `${102}`. – chepner Sep 21 '21 at 16:53
  • 3
    @chepner on zsh, `echo "file$102_a.txt"` produces `file_a.txt`, and in fish shell, it produces `file.txt` – smac89 Sep 21 '21 at 16:55
  • I'm running the script from the shell. In the case of my toy example, it actually stores `"file_a.txt"`. However, the files I am working with are long file names with a proper extension, e.g. Under Get Info the name and extension is "bi+VxbdVx9bVxa1Vxe7hVx05Vx8fp(VxdfVxb31Vx84Vx80Vx01VxbbVx17Vxa1Vxe3Vx08bVx91Vx03)Vxed2Vxa2wVx87UVxa5i" – amc007 Sep 21 '21 at 16:56
  • 1
    @smac89 Yeah, that's a nonstandard feature of `zsh`. POSIX requires multi digit parameters be enclosed in braces. (Though I think it's perfectly reasonable for `zsh` to behave that way, and the POSIX requirement probably stems more from historical precedent and existing behavior.) – chepner Sep 21 '21 at 16:58
  • @amc007 You are using `zsh`, which as smac89 points out, treats `$102` as a parameter expansion, not literal text, inside double quotes. – chepner Sep 21 '21 at 16:59
  • @chepner thanks, I am using zsh. I tried using iTerm and that resulted in the same issue. – amc007 Sep 21 '21 at 17:03
  • 1
    `zsh` is a shell that runs *in* your terminal, whether you are using Terminal or iTerm. – chepner Sep 21 '21 at 17:04
  • @amc007, short answer: Use single quotes, not double quotes. `'file$102_a.txt'`, not `"file$102_a.txt"` – Charles Duffy Sep 21 '21 at 17:05
  • (not an argparse-specific question or answer at all; the unwanted substitution happens before the Python interpreter even starts, so _long_ before it loads the `argparse` library). – Charles Duffy Sep 21 '21 at 17:07

1 Answers1

1

We can pass it with an escape sequence before the dollar sign.

Say test.py is defined as

import sys
print(sys.argv[1])

Then,

$ python test.py "dff\$sdfs"

Would print dff$sdfs

EDIT: As pointed out by user: smac89, if the arguments are enclosed within single quotes ('), instead of double quotes ("), it will not split at the dollar sign.

$ python test.py 'dff$sdfs'

Would also print dff$sdfs

lifezbeautiful
  • 1,160
  • 8
  • 13
  • 3
    Worth pointing out that this has nothing to do with argparse or Python, but that it is a feature of the shell. – Jasmijn Sep 21 '21 at 16:45
  • Thanks. While this does work as you said, I was hoping to find a solution that wouldn't involve reconfiguring the argument. I have thousands of files and a csv file containing all their names with other metadata. That said, if it comes down to it that is likely what I'll end up doing – amc007 Sep 21 '21 at 16:58
  • 2
    @amc007 you don't have to do that. See the duplicate link and you will find that another way to get around this is to just 'single' quote the argument from the shell, not double quote – smac89 Sep 21 '21 at 17:00
  • @smac89, Thanks! That was precisely the kind of solution I was looking for. – amc007 Sep 21 '21 at 17:05