Как расширить этот скрипт на python, чтобы он вводил данные пользователем из командной строки вместо запроса? - PullRequest
0 голосов
/ 23 августа 2011

В настоящее время у меня есть скрипт на python, который принимает текстовый файл, проверяет фрагменты, заключенные в тег ## Somethinghere ##, и спрашивает пользователя, сколько раз он / она хочет скопировать его. Например, если у меня есть текстовый файл:

Random Text File

##RandomLine1##
Random Line 1
##RandomLine1##

Random Line 2

##RandomLine3##
Random Line 2
##RandomLine3##

End of file

Пользователю предлагается:

Loop "RandomLine1" how many times?
Loop "RandomLine3" how many times?

Как только пользователь вводит числа, определенные вложенные строки копируются указанное количество раз, а теги удаляются. Однако после многократного копирования текст выводится в указанный выходной файл.

Для запуска скрипта команда выглядит так:

python script.py inputfile outputfile

Что я хочу сделать, это вместо того, чтобы предлагать пользователю ввести данные, пользователь может при желании ввести число циклов в качестве необязательных параметров командной строки. Что-то вроде:

python script.py inputfile outputfile --RandomLine1 2 --RandomLine3 2

Возможно ли это для скрипта на python? Я прилагаю текущую версию скрипта ниже:

import re
import argparse

pattern = '##([^#]*)##'

def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('infile', type=argparse.FileType('r'))
    parser.add_argument('outfile', type=argparse.FileType('w'))
    args = parser.parse_args()

    matcher = re.compile(pattern)
    tagChecker = False
    strList = []
    for line in args.infile:
        if tagChecker is True:
            lineTest = matcher.search(line)
            if lineTest:
                tagChecker = False
                for _ in range(int(raw_input('Loop ' + lineTest.string[2:-3] + ' how many times?')) - 1):
                    for copyLine in strList:
                        args.outfile.write(copyLine)
                new_line = matcher.sub("", line)
                args.outfile.write(new_line)
                strList = []
                continue
            else:
                strList.append(line)
                args.outfile.write(line)
        if tagChecker is False:
            lineTest = matcher.search(line)
            if lineTest:
                tagChecker = True
                new_line = matcher.sub("", line)
                args.outfile.write(new_line)
            else:
                args.outfile.write(line)

    args.infile.close()
    args.outfile.close()

if __name__ == '__main__':
    main()

Ответы [ 2 ]

2 голосов
/ 23 августа 2011

Как насчет использования sys.argv?

sys.argv возвращает список аргументов, переданных вашему сценарию, через пробел, с sys.argv[0], являющимся именем сценария.

Так для следующей программы:

import sys
print sys.argv

при запуске следующим образом:

python script.py inputfile outputfile --RandomLine1 2 --RandomLine3 2

будет выдавать следующий вывод:

['script.py', 'inputfile', 'outputfile', '--RandomLine1', '2', '--Randomline3', '2']

Если вы хотите создать словарь строк и соответствующих аргументов, попробуйте что-то вроде следующего:

# Get portion of list that isn't the script name or input/output file name
args = sys.argv[3:]
args_dict = {}

i = 0
while i < len(args):
    if args[i].startswith('--'):
        line = args[i].replace('--', '')
        try:
             args_dict[line] = int(arg[i+1])
        except IndexError:
             print "%s has no argument" % line
        i += 1

Для вашего входного примера мы получим args_dict == {'RandomLine1': 2, 'RandomLine3': 2}.Я думаю, довольно легко понять, как использовать словарь для любых целей.

Приведенный выше код, конечно, можно выполнить более / менее тщательно, в зависимости от того, насколько надежным вы ожидаете ввода.

2 голосов
/ 23 августа 2011

Да, вы можете сделать это, добавив значения по умолчанию к вашим аргументам:

parser.add_argument("--RandomLine1", default=None)
# same for RandomLine2

# ...

if args.RandomLine1 is not None:
    # use args.RandomLine1 as a number
    #...
else:
    # RandomNumber1 is not given in the args
    #...
...