[英]Parser in python3 does not take delimiter values from commandline via argparse
[英]Take multiple patterns from cli. argparse Python3
我有一个grep的python版本,我正在为一项任务而构建。 我希望我的python模块从命令行采用多种模式,就像grep一样。 但是,无论我做什么,我都会与“调试”参数发生冲突。
这是当前从命令行(带有-h)的样子:
pgreper.py [-h] [--debug] pattern
目前,我只能使用一种模式进行搜索:
cat input.txt | ./pgreper.py "were"
我希望能够使用多种模式来搜索input.txt文件:
cat input.txt | ./pgreper.py "were" "you"
但是,当我尝试执行此操作时,出现以下错误:
pgreper.py: error: unrecognized argument: you
我知道这与我生成一个通过读取sys.argv [1]进行搜索的模式有关。 我将如何编辑脚本,以使其能够从sys.argv中采用多种模式,而又不影响已实现的可选参数?
非常感谢 :)
ps,请忽略我的评论,谢谢。
#!/usr/bin/python3
import sys
import re
import time
import datetime
import inspect
import argparse
parser = argparse.ArgumentParser(description='Python Grep.')
parser.add_argument('--debug', default='debug', action='store_true', help='Print debug messages')
parser.add_argument('pattern', type=str, help='Pattern for pgrepping')
args = parser.parse_args()
class CodeTrace(object):
def __init__(self, line, pattern):
self.line = line
self.pattern = pattern
# @staticmethod
def trace(self, line, pattern):
# Creating Timestamp
ts = time.time()
# Formatting Timestamp
ts = datetime.datetime.fromtimestamp(ts).strftime('[%Y-%m-%d %H:%M:%S:%f]')
stack = inspect.stack()
# Retrieve calling class information
the_class = stack[1][0].f_locals["self"].__class__
# Retrieve calling method information
the_method = stack[1][0].f_code.co_name
the_variables = stack[1][0].f_code.co_varnames
# Formats the contents of the debug trace into a readable format,
# Any parameters passed to the method and the return value, are included in the debug trace
debug_trace = ("{} {}.{}.{} {} {} ".format(ts, str(the_class), the_method, the_variables, pattern, line))
# Send out the debug trace as a standard error output
sys.stderr.write(debug_trace + "\n")
class Grepper(object):
def __init__(self, pattern):
self.pattern = pattern
# @CodeTrace.trace()
def matchline(self, pattern):
regex = re.compile(self.pattern)
for line in sys.stdin:
if regex.search(line):
sys.stdout.write(line)
if args.debug != 'debug':
(CodeTrace(line, pattern).trace(line, pattern))
def main():
pattern = str(sys.argv[1])
print(sys.argv)
Grepper(pattern).matchline(pattern)
if __name__ == "__main__":
main()
您可以使用nargs
关键字参数告诉argparse
期望1个或多个参数 :
parser.add_argument('patterns', type=str, nargs='+', help='Pattern(s) for pgrepping')
这里+
表示1或更大 。 然后,您可以组合以下模式:
pattern = '|'.join(['(?:{})'.format(p) for p in args.patterns])
并将其传递给您的grepper。 模式与|
首先将其置于非捕获组( (?:...)
)中以确保将每个模式都视为不同的。
我将所有参数解析都放在main()
函数中:
def main():
parser = argparse.ArgumentParser(description='Python Grep.')
parser.add_argument('--debug', action='store_true', help='Print debug messages')
parser.add_argument('pattern', type=str, nargs='+', help='Pattern(s) for pgrepping')
args = parser.parse_args()
pattern = '|'.join(['(?:{})'.format(p) for p in args.pattern])
Grepper(pattern, args.debug).matchline()
我还删除了--debug
选项的默认设置。 使用store_true
意味着它将默认为False
; 然后,您可以简单地测试args.debug
是否为true。
您不需要将pattern
两次传递给Grepper()
; 你可以简单地使用self.pattern
在matchline
的方法,贯穿始终。 相反,我也会将args.debug
传递给Grepper()
(无需使其成为全局Grepper()
)。
参数解析外观的快速演示,包括帮助消息:
>>> import argparse
>>> parser = argparse.ArgumentParser(description='Python Grep.')
>>> parser.add_argument('--debug', action='store_true', help='Print debug messages')
_StoreTrueAction(option_strings=['--debug'], dest='debug', nargs=0, const=True, default=False, type=None, choices=None, help='Print debug messages', metavar=None)
>>> parser.add_argument('pattern', type=str, nargs='+', help='Pattern(s) for pgrepping')
_StoreAction(option_strings=[], dest='pattern', nargs='+', const=None, default=None, type=<type 'str'>, choices=None, help='Pattern(s) for pgrepping', metavar=None)
>>> parser.print_help()
usage: [-h] [--debug] pattern [pattern ...]
Python Grep.
positional arguments:
pattern Pattern(s) for pgrepping
optional arguments:
-h, --help show this help message and exit
--debug Print debug messages
>>> parser.parse_args(['where'])
Namespace(debug=False, pattern=['where'])
>>> parser.parse_args(['were'])
Namespace(debug=False, pattern=['were'])
>>> parser.parse_args(['were', 'you'])
Namespace(debug=False, pattern=['were', 'you'])
>>> parser.parse_args(['--debug', 'were', 'you'])
Namespace(debug=True, pattern=['were', 'you'])
模式如下所示:
>>> args = parser.parse_args(['were', 'you'])
>>> args.pattern
['were', 'you']
>>> pattern = '|'.join(['(?:{})'.format(p) for p in args.pattern])
>>> pattern
'(?:were)|(?:you)'
相反,如果您希望所有模式都匹配,则需要更改Grepper()
以采用多种模式并测试所有这些模式。 使用all()
函数来提高效率(仅测试所需数量的模式):
def main():
parser = argparse.ArgumentParser(description='Python Grep.')
parser.add_argument('--debug', action='store_true', help='Print debug messages')
parser.add_argument('pattern', type=str, nargs='+', help='Pattern(s) for pgrepping')
args = parser.parse_args()
Grepper(args.pattern, args.debug).matchline()
Grepper
类变为:
class Grepper(object):
def __init__(self, patterns, debug=False):
self.patterns = [re.compile(p) for p in patterns]
self.debug = debug
def matchline(self, debug):
for line in sys.stdin:
if all(p.search(line) for p in self.patterns):
sys.stdout.write(line)
if self.debug:
CodeTrace(line, self.patterns).trace(line)
对CodeTrace
类进行适当的调整。
您的argparse参数配置不正确。 现在,这实际上就是您配置参数的方式。 检查Python文档中的argparse,因为那里有一个很好的例子。
格式应始终为yourscript.py -aARGUMENTVAL -bARGUMENTVAL ...etc.
-a和-b样式很重要。
您的代码经过编辑,可以更好地使用argparse模块。 看看这是否更好(没有用于调试的动作参数):
import sys
import re
import time
import datetime
import inspect
import argparse
parser = argparse.ArgumentParser(description='Python Grep.')
parser.add_argument('-p', '--pattern', type=str, help='Pattern for pgrepping')
parser.add_argument('-d','--debug', type=str, default="false", help='Print debug messages')
args = vars(parser.parse_args());
class CodeTrace(object):
def __init__(self, line, pattern):
self.line = line
self.pattern = pattern
# @staticmethod
def trace(self, line, pattern):
# Creating Timestamp
ts = time.time()
# Formatting Timestamp
ts = datetime.datetime.fromtimestamp(ts).strftime('[%Y-%m-%d %H:%M:%S:%f]')
stack = inspect.stack()
# Retrieve calling class information
the_class = stack[1][0].f_locals["self"].__class__
# Retrieve calling method information
the_method = stack[1][0].f_code.co_name
the_variables = stack[1][0].f_code.co_varnames
# Formats the contents of the debug trace into a readable format,
# Any parameters passed to the method and the return value, are included in the debug trace
debug_trace = ("{} {}.{}.{} {} {} ".format(ts, str(the_class), the_method, the_variables, pattern, line))
# Send out the debug trace as a standard error output
sys.stderr.write(debug_trace + "\n")
class Grepper(object):
def __init__(self, pattern):
self.pattern = pattern
# @CodeTrace.trace()
def matchline(self, pattern):
regex = re.compile(self.pattern)
for line in sys.stdin:
if regex.search(line):
sys.stdout.write(line)
if args.debug != 'debug':
(CodeTrace(line, pattern).trace(line, pattern))
def main():
pattern = str(args['pattern'])
print(sys.argv)
Grepper(pattern).matchline(pattern)
if __name__ == "__main__":
main()
您可以提供逗号分隔的字符串来分隔模式-`p。 为此使用python强大的字符串函数
pattern = ((args['pattern']).replace(" ", "")).split(",");
以上将为您提供要查找的模式列表?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.