我正在编写一个Python脚本,该脚本需要一个正则表达式模式和一个文件名,并在文件中查找该正则表达式模式。
默认情况下,脚本需要一个文件来处理。
我想更改脚本,因此默认情况下,除非指定了文件(-f文件名),否则它将采用来自STDIN的输入。
我的代码如下:
#!/usr/bin/env python3
# This Python script searches for lines matching regular expression -r (--regex) in file/s -f (--files).
import re
import argparse
#import sys
class colored:
CYAN = '\033[96m'
UNDERLINE = '\033[4m'
END = '\033[0m'
def main(regex, file, underline, color):
pattern = re.compile(regex)
try:
for i, line in enumerate(open(file, encoding="ascii")):
for match in re.finditer(pattern, line):
message = "Pattern {} was found on file: {} in line {}. The line is: ".format(regex, file, i+1)
if args.color and args.underline:
#message = "Pattern {} was found on file: {} in line {}. The line is: ".format(regex, file, i+1)
l = len(line)
print(message + colored.CYAN + line + colored.END, end="")
print(" " ,"^" * l)
break
if args.underline:
l = len(line)
print(message + line, end="")
print(" " ,"^" * l)
break
if args.color:
print(message + colored.CYAN + line + colored.END, end="")
break
if args.machine:
print("{}:{}:{}".format(file, i+1, line), end="")
break
else:
print(message + line, end="")
break
except FileNotFoundError:
print("File not found, please supply")
pass
if __name__ == "__main__":
parser = argparse.ArgumentParser(description='Python regex finder', epilog = './python_parser.py --regex [pattern] --files [file]')
requiredNamed = parser.add_argument_group('required named arguments')
requiredNamed.add_argument('-r', '--regex',
help='regex pattern', required=True)
parser.add_argument('-f', '--file',
help='file to search pattern inside')
parser.add_argument('-u', '--underline', action='store_true',
help='underline')
parser.add_argument('-c', '--color', action='store_true',
help='color')
parser.add_argument('-m', '--machine', action='store_true',
help='machine')
args = parser.parse_args()
main(args.regex, args.file, args.underline, args.color)
您可以看到跑步here的样子。
我尝试使用答案from this SO question,但收到以下错误:
for i, line in enumerate(open(file, encoding="ascii")):
TypeError: expected str, bytes or os.PathLike object, not _io.TextIOWrapper
编辑#1 :
这是文件:
Itai
# something
uuu
UuU
# Itai
# this is a test
this is a test without comment
sjhsg763
3989746
# ddd ksjdj #kkl
不提供文件时出现上述错误。
编辑#2 :
当我将文件参数更改为该参数时:
parser.add_argument('-f', '--file',
help='file to search pattern inside',
default=sys.stdin,
type=argparse.FileType('r'),
nargs='?'
)
然后像这样运行脚本:
~ echo Itai | ./python_parser.py -r "[a-z]" -m
Traceback (most recent call last):
File "./python_parser.py", line 59, in <module>
main(args.regex, args.file, args.underline, args.color)
File "./python_parser.py", line 16, in main
for i, line in enumerate(open(file, encoding="ascii")):
TypeError: expected str, bytes or os.PathLike object, not NoneType
➜ ~
args.file = tmpfile
这是脚本运行所在目录中的文件。
我在做什么错了?
答案 0 :(得分:2)
您是这样写的:
def main(regex, file, underline, color):
...
for i, line in enumerate(open(file, encoding="ascii")):
对于file
是文件名还是打开的文件描述符,您有些困惑。您希望它是一个打开的文件描述符,因此您可以传入sys.stdin
。这意味着main()
不应尝试open()
,而应依靠调用者传递已经打开的文件描述符。
将调用open()
推到main()
的责任将使您默认分配file = sys.stdin
,然后重新分配open()
的结果,如果发现已指定文件名。