2013-11-19 2 views
1

Я создаю простой файл в python для реорганизации некоторых текстовых данных, которые я захватил с веб-сайта. Я помещаю данные в файл .txt, а затем хочу использовать команду «хвост», чтобы избавиться от первых 5 строк. Я могу сделать эту работу для простого имени файла, показанного ниже, но когда я пытаюсь изменить имя файла (к тому, что мне действительно нравится), я получаю сообщение об ошибке. Мой код:Задание имени файла в вызове os.system из python

start = 2010 
end = 2010 
for i in range(start,end+1) 
    year = str(i) 

    ...write data to a file called file... 

    teamname=open(file).readline() # want to use this in the new filename 
    teamfname=teamname.replace(" ","") #getting rid of spaces 

    file2 = "gotdata2_"+year+".txt" 
    os.system("tail -n +5 gotdata_"+year+".txt > "+file2) 

Приведенный выше код работает, как задумано, создавая файл, а затем создать file2, исключающую первые 5 строк файла. Однако, когда я изменить имя file2 быть:

file2 = teamfname+"_"+year+".txt" 

Я получаю ошибку:

Sh: Строка 1: _2010.txt: команда не найдена

Это как если бы конец моя инструкция file2 отрубается, а часть .txt не распознается. В этом случае мой код выводит файл, но в конце отсутствует _2010.txt. Я дважды проверял, что и год, и teamfname являются строками. Я также пробовал его с пробелами и без пробелов в строке teamfname. Я получаю ту же ошибку, когда я пытаюсь включить оператор os.system mv, который переименует файл в то, что я хочу, так что должно быть что-то не так с моим пониманием того, как указать здесь строку.

Есть ли у кого-нибудь идеи о том, что вызывает это? Я не смог найти решение, но я нашел эту проблему трудной для поиска.

+0

Во-первых, вы попробовали «распечатать», что такое 'file2', и, если на то пошло, что такое целая строка командной строки? Это намного проще, чем пытаться угадать, что это должно быть основано на третьей ошибке от оболочки. – abarnert

+2

Во-вторых, почему вы используете 'os.system' в первую очередь? [Документация] (http://docs.python.org/2/library/os#os.system) явно говорит вам, что «подпроцесс» проще и мощнее. В частности, 'subprocess' позволяет вам передавать список аргументов вместо того, чтобы пытаться выяснить, как процитировать пробелы и кавычки, а также использовать специальные символы и т. Д. - другими словами, именно то, что вы здесь видите. – abarnert

+0

@abarnert Я не думаю, что документы говорят что-нибудь о «подпроцессе» проще, иначе они будут лгать. Я обожаю Python всем сердцем, но API-интерфейсы подпроцесса (sic) не являются его сильной стороной. Тем не менее, 'os.system' - это не-ход, конечно. –

ответ

2

Не зная, каковы ваши фактические строки, невозможно быть уверенным в чем проблема. Тем не менее, это почти наверняка связано с неудачей правильной цитаты и/или исключения аргументов для командной строки.

Мое первое предположение, что у вас есть новая строка в середине вашего имени файла, а оболочка обрезает команду в новой строке. Но я бы не стал делать ставку на это слишком сильно. Если вы на самом деле распечатали имя пути, я мог бы точно сказать вам. Но зачем проходить эту головную боль?

Решение практически любых проблем с os.system не должно использоваться os.system.

Если посмотреть на the docs, они даже сказать вам следующее:

The subprocess module provides more powerful facilities for spawning new processes and retrieving their results; using that module is preferable to using this function. See the Replacing Older Functions with the subprocess Module section in the subprocess documentation for some helpful recipes.

Если вы используете subprocess вместо os.system, вы можете избежать оболочки полностью. Вы также можете передавать аргументы в виде списка вместо того, чтобы пытаться выяснить, как их цитировать, и избегать их должным образом. Который полностью избегал бы точной проблемы, с которой вы сталкиваетесь.

Например, если вы сделаете это:

file2 = "gotdata2_"+year+".txt" 
with open(file2, 'wb') as f: 
    subprocess.check_call(['tail', '-n', '+5', "gotdata_"+year+".txt"], stdout=f) 

Затем, если вы меняете, что первая линия к этому:

file2 = teamfname+"_"+year+".txt" 

Это будет работать, даже если teamfname имеет место или цитату или другой особый символ.


Это, как говорится, я не знаю, почему вы хотите использовать tail в первую очередь. Вы можете пропустить первые 5 строк так же легко непосредственно в Python.

Смежные вопросы