Передача мета-символов Python в качестве аргументов из командной строки

я делаю программу Python, которая будет анализировать поля в некоторых входных строках. Я хотел бы позволить пользователю ввести разделитель полей в качестве опции из командной строки. Я использую optparse для этого. Я сталкиваюсь с проблемой, которая вводит что-то вроде t отделится буквально на t, а не на вкладке, что и я хочу. Я уверен, что это вещь Python, а не оболочка, так как я пробовал каждую комбинацию кавычек, обратных косых черт и t's, что я могу думать из.

если бы я мог сделать optparse чтобы аргумент был простым вводом (есть ли такая вещь?), а не raw_input, Я думаю, что это сработает. Но я понятия не имею, как это сделать.

я также пробовал различные замены и трюки с регулярным выражением, чтобы превратить строку из двух символов "t" на вкладке один символ, но без успеха.

пример, где input.txt - это:

field 1[tab]fieldt2

(Примечание: [tab] закладка характера и fieldt2 - это 8 символов)

parseme.py:

#!/usr/bin/python
from optparse import OptionParser  
parser = OptionParser()  
parser.add_option("-d", "--delimiter", action="store", type="string",  
    dest="delimiter", default='t')  
parser.add_option("-f", dest="filename")  
(options, args) = parser.parse_args()  
Infile = open(options.filename, 'r')  
Line = Infile.readline()  

Fields = Line.split(options.delimiter)  
print Fields[0]  
print options.delimiter  

Infile.close()  

это дает мне:

$ parseme.py -f input.txt  
field 1  
[tab]

Эй, отлично, настройка по умолчанию работала правильно. (Да, я знаю, что могу просто сделать T по умолчанию и забыть об этом, но я хотел бы знать, как справиться с этим типом проблемы.)

$ parseme.py -f input.txt -d 't'  
field 1[tab]field  
t

это не то, что я хочу.

4 ответов


>>> r'\t\n\v\r'.decode('string-escape')
'\t\n\x0b\r'

быстрый и грязный способ, чтобы eval, вот так:

eval(options.delimiter, {}. {})

дополнительные пустые дикты существуют для предотвращения случайного clobbering вашей программы.


решение его из вашего скрипта:

options.delimiter = re.sub("\\t","\t",options.delimiter)

вы можете адаптировать re, чтобы соответствовать более экранированным символам (\n, \r и т. д.)

другой способ решить проблему за пределами python:

когда вы вызываете свой скрипт из оболочки, сделайте это так:

parseme.py -f input.txt -d '^V<tab>'

^V означает "нажмите Ctrl+V"

затем нажмите клавишу обычной вкладки

это правильно передаст символ вкладки в ваш скрипт python;


на callback опция-хороший способ справиться с сложными случаями:

parser.add_option("-d", "--delimiter", action="callback", type="string",
                  callback=my_callback, default='\t')

С соответствующей функцией (должна быть определена до парсер, потом):

def my_callback(option, opt, value, parser):
    val = value
    if value == '\t':
        val = '\t'
    elif value == '\n':
        val = '\n'
    parser.values.delimiter = val

вы можете проверить это работает через командную строку: python test.py -f test.txt -d \t (нет цитаты вокруг \t, они бесполезны).

он имеет преимущество обработки опции через модуль "optparse", а не через постобработку результатов анализа.