аргумент командной строки, за которым следует опция argparse - PullRequest
0 голосов
/ 29 апреля 2018

Я новичок в python и в настоящее время играюсь с argpase. Я пытаюсь вызвать функцию, используя путь к каталогу, указанный в качестве аргумента командной строки, за которым следует опция argparse (-name) и регулярное выражение, которое просматривает все файлы в каталоге и выплевывает все совпадения с регулярным выражением, как показано ниже. :

./find.py ../seek -name '[a-z]*\.txt'

Однако я получаю сообщение об ошибке, похожее на

usage: find.py [-h] [--path PATH] [-name] [--regex REGEX] find.py: error: unrecognized arguments: . . / s e e k / p r o g r a m . c

И без -name он просто печатает все файлы внутри пути.

Вот что у меня есть:

#!/usr/bin/python2.7

import os, sys, argparse,re 
from stat import *

def parse(argv=None):
   parser = argparse.ArgumentParser()
   parser.add_argument('--path', help='path of directory', action='store')
   parser.add_argument('-name', '--name', action='store_true')
   parser.add_argument('--regex', default=r"[a-z0-9A-Z]")
   args = parser.parse_args(argv)
   print(args)
   return args

def main(argv=None):

   direc = sys.argv[1]
   files = []

   for f in os.listdir(direc):
      pathname = os.path.join(direc, f)
      mode = os.stat(pathname).st_mode

      if S_ISREG(mode):  
         args = parse(pathname)      
         if args.name:  
            dirls = [re.match(args.regex, pathname)]
            print(dirls)
         else:
            print pathname

if __name__ == '__main__':main() 

Есть мысли?

Ответы [ 2 ]

0 голосов
/ 06 февраля 2019

Пример анализатора аргумента PATH : добавлен другой тип аргументов с пользовательскими обработчиками. Для пути здесь вы можете передать '-path' с последующим значением пути в качестве аргумента

import os
import argparse
from datetime import datetime


def parse_arguments():
    parser = argparse.ArgumentParser(description='Process command line arguments.')
    parser.add_argument('-path', type=dir_path)
    parser.add_argument('-e', '--yearly', nargs = '*', help='yearly date', type=date_year)
    parser.add_argument('-a', '--monthly', nargs = '*',help='monthly date', type=date_month)

    return parser.parse_args()


def dir_path(path):
    if os.path.isdir(path):
    return path
    else:
    raise argparse.ArgumentTypeError(f"readable_dir:{path} is not a valid path")


def date_year(date):
    if not date:
    return

    try:
    return datetime.strptime(date, '%Y')
    except ValueError:
    raise argparse.ArgumentTypeError(f"Given Date({date}) not valid")


def date_month(date):
    if not date:
    return

    try:
    return datetime.strptime(date, '%Y/%m')
    except ValueError:
    raise argparse.ArgumentTypeError(f"Given Date({date}) not valid")


def main():
    parsed_args = parse_arguments()

if __name__ == "__main__":
main()
0 голосов
/ 02 мая 2018

Чтобы ваша программа работала, вам нужен путь. Таким образом, опция --path должна принимать аргумент. Измените вашу parse() функцию, чтобы изменить строку

parser.add_argument('--path', help='path of directory', action='store')

до

parser.add_argument('--path', help='path of directory', action='store', required=True)

Вам нужно позвонить parse_args() только один раз. Удалите вызов parse() в верхней части цикла.

А тебе не нужно делать

direc = sys.argv[1]

если вы используете argparse.

re.match() возвращает match объект , который, вероятно, не тот, который вы хотите напечатать.

Возможно, вы захотите взглянуть на match() против search().

Функция match() проверяет только совпадение RE в начале строки, в то время как search() будет сканировать строку в поисках совпадения.

Если вы хотите напечатать имена файлов, соответствующие регулярному выражению, вы можете сделать

  if S_ISREG(mode):  
     #args = parse(pathname)      
     if args.name:  
        #dirls = re.match(args.regex, pathname)
        dirls = re.search(args.regex, pathname)
        if( dirls ):
           print(pathname)
     else:
        print pathname

Так что main() должно быть что-то вроде

def main(argv=None):
    args = parse(sys.argv[1:])
    print(args)
    #direc = sys.argv[1]
    direc = args.path
    files = []

    for f in os.listdir(direc):
      pathname = os.path.join(direc, f)
      mode = os.stat(pathname).st_mode

    if S_ISREG(mode):  
       #args = parse(pathname)      
       if args.name:  
          #dirls = re.match(args.regex, pathname)
          dirls = re.search(args.regex, pathname)
          if( dirls ):
             print(pathname)
       else:
          print pathname

Чтобы указать регулярное выражение, совпадающее с именами файлов, необходимо указать регулярное выражение, используя параметр --regex. По умолчанию вы сделали так, чтобы соответствовать именам, имеющим только цифры и (английские) буквы.

./find.py --path ../seek -name --regex [a-z]\*.txt

или

./find.py --path ../seek -name --regex '[a-z]*.txt'
...