3

Is there a way to call my program in python and pass it a string I want it to parse without declaring the string as 'String I want to parse' but as String I want to parse

import argparse

#Parse command line for input
parser = argparse.ArgumentParser(description='Parse input string')
#position input argument
parser.add_argument('string', help='Input String')

args = parser.parse_args()
arg_str = args.string

print(arg_str)

when I run $ python test.py String I want to parse I get the error: test.py: error: unrecognized arguments: I want to parse

Is there anyway to tell the script to account for spaces and take the input as one string until either the end of the input is reached or another parse argument such as -s is reached?

1
  • It is possible to use sys.argv that retrieves all the arguments of the command line in a list, and then build your string inside your program by parsing this list. Commented Dec 13, 2015 at 21:08

4 Answers 4

4

The "correct" approach is as already mentioned. But OP specifically asked:

I want it to parse without declaring the string as 'String I want to parse' but as String I want to parse

It is possible to do this with a custom action. The advantage of this approach over simply joining sys.argv[1:] is to address the following:

Is there anyway to tell the script to account for spaces and take the input as one string until either the end of the input is reached or another parse argument such as -s is reached?

We can add other options without them being mopped up into the 'string' argument:

import argparse

class MyAction(argparse.Action):
    def __call__(self, parser, namespace, values, option_string=None):
        setattr(namespace, self.dest, ' '.join(values))

parser = argparse.ArgumentParser(description='Parse input string')
parser.add_argument('string', help='Input String', nargs='+', action=MyAction)
parser.add_argument('--extra', '-s', help='Another Option!')

args = parser.parse_args()
print args

Demo:

$ python example.py abc def ghi
Namespace(extra=None, string='abc def ghi')
$ python example.py abc def ghi -s hello
Namespace(extra='hello', string='abc def ghi')
$ python example.py -s hello abc def ghi 
Namespace(extra='hello', string='abc def ghi')
Sign up to request clarification or add additional context in comments.

Comments

3

The problem is you give five arguments instead of one. Put your string with space between double quote and it will work.

~ ❯❯❯ python test.py asd asd
usage: test.py [-h] string
test.py: error: unrecognized arguments: asd
~ ❯❯❯ python test.py "asd asd"
asd asd
~ ❯❯❯

1 Comment

Thanks for the input @Just but I want my input to be typed without quotes
2

If you really want to use argparse add nargs='+' or nargs='*' to add_argument:

import argparse
parser = argparse.ArgumentParser(description='Parse input string')
parser.add_argument('string', help='Input String', nargs='+')
args = parser.parse_args()
arg_str = ' '.join(args.string)
print(arg_str)

python test.py abc xyz will produce abc xyz. * means that empty list is ok and + requires at least one word.

Alternatively you may just user sys.arg if you don't need anything fancy:

import sys
arg_str = ' '.join(sys.argv[1:])  # skip name of file
print(arg_str)

And if I may, I really like docopt so I would recommend it:

"""Usage:
  test.py <input>...
"""

import docopt
arguments = docopt.docopt(__doc__)
input_argument = ' '.join(arguments['<input>'])
print(input_argument)

Docopt generates parser based on help message, it's so great.

6 Comments

Thank you this is great. Can you explain to me what: arg_str = ' '.join(args.string) is doing?
When you use nargs then args.string is a list of strings, not single string (so the name of variable is unfortunate). ' '.join(['a', 'b', 'c'] results in 'a b c'.
This approach may get hairy once "either the end of the input is reached or another parse argument such as -s is reached" , as mentioned in the question. If there are other options to parse, there will be some interesting coding required
why? in my (not so extensive) experience it works and documentation of nargs doesn't mention any restrictions, it even gives example like this >>> parser.add_argument('--bar', nargs='*') >>> parser.add_argument('baz', nargs='*')
Sorry, I was talking about the option to use ' '.join(sys.argv[1:]). Ideally I think this joining should be done by the ArgumentParser instance, rather than by manual post-processing on the args
|
0

You could just concatenate all arguments together until an argument starts with -

import sys

new_args = []
for arg in sys.argv:
   if arg.startswith("-") or len(new_args) == 0:
      new_args.append(arg)
   else:
      new_args[-1] += arg

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.