Проблема с форматированием при использовании awk в скрипте Python - PullRequest
0 голосов
/ 07 сентября 2018

Я пытаюсь написать следующую команду в скрипте Python:

cmd = '''awk '{printf "%.6f  %.6f  %.6f\n",$1-10.0,$2,$3}' %s.txt > %s.txt''' % (file_name_1, file_name_2)
call(cmd, shell=True)

Но не удалось выполнить из-за проблемы с аргументом. Первые три "%.6f" для выходного формата awk, последние два "%s" для имени файла. Я пытался добавить "r" после "=", но это не работает.

Спасибо!

Ответы [ 2 ]

0 голосов
/ 07 сентября 2018

Вам нужно удвоить % в строке формата, чтобы вставить буквенные символы процента в результирующую строку

cmd = r'''awk '{printf "%%.6f  %%.6f  %%.6f\n",$1-10.0,$2,$3}' %s.txt > %s.txt''' % (file_name_1, file_name_2)
# ......................^^.....^^.....^^

Как в:

$ python
Python 2.7.12 (default, Dec  4 2017, 14:50:18) 
[GCC 5.4.0 20160609] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> file_name_1 = 'foo'
>>> file_name_2 = 'bar'
>>> cmd = '''awk '{printf "%.6f  %.6f  %.6f\n",$1-10.0,$2,$3}' %s.txt > %s.txt''' % (file_name_1, file_name_2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: float argument required, not str
>>> cmd = r'''awk '{printf "%%.6f  %%.6f  %%.6f\n",$1-10.0,$2,$3}' %s.txt > %s.txt''' % (file_name_1, file_name_2)
>>> cmd
'awk \'{printf "%.6f  %.6f  %.6f\\n",$1-10.0,$2,$3}\' foo.txt > bar.txt'
0 голосов
/ 07 сентября 2018

символ \n в команде не передается awk как \n, но как перевод строки в командной строке.

Вам необходимо использовать префикс raw, чтобы \n передавался буквально:

cmd = r'''awk '{printf "%.6f  %.6f  %.6f\n",$1-10.0,$2,$3}' %s.txt > %s.txt''' %  (file_name_1, file_name_2)

(и да, благодаря прочтению другого ответа Гленна , я увидел, что забыл удвоить символ %, так что на самом деле это не очень удобное решение, если вы не используете format вместо этого, исправление только частичный)

с использованием str.format и двойных кавычек (здесь нет необходимости в тройных одинарных кавычках):

cmd = r"awk '{printf "%.6f  %.6f  %.6f\n",$1-10.0,$2,$3}' {}.txt > {}.txt".format(file_name_1, file_name_2)

Еще лучше, переписать это на чистом питоне, используя open, str.split для повторяющихся строк и преобразования с плавающей запятой. Не проверено, но должно отлично работать:

with open(file_name_1+".txt") as fr, open(file_name_2+".txt","w") as fw:
    for line in fr:
      toks = [float(x) for x in line.split()]
      fw.write("%.6f  %.6f  %.6f\n" % (toks[0]-10,toks[1],toks[2]))
  • более портативный (не нужно awk, например, в Windows)
  • если в именах файлов есть пробелы, это не проблема
  • избегает системного вызова
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...