Использование `printf` для печати переменной, содержащей знак процента `%`, приводит к "bash: printf: `p': недопустимый символ формата"

Мы можем обрезать начальные и закрывающие скобки с помощью tr, а затем использовать awkдля очень простых математических вычислений:

$ tr -d '[]' < input | awk -F: '{secs=$3; secs+=$2*60; secs+=$1*60*60; printf "%.3f\n", secs*1000 }'
55798496.640
55798496.644
55798496.665
55798496.682
55798497.096
55798498.621

Чтобы показать и ввод, и вывод (с фигурными скобками, прикрепляемыми к ), мы просто расширяем оператор printf:

$ tr -d '[]' < input | awk -F: '{secs=$3; secs+=$2*60; secs+=$1*60*60; printf "[%s]\t%.3f\n", $0,secs*1000 }'
[15:29:58.496640]   55798496.640
[15:29:58.496644]   55798496.644
[15:29:58.496665]   55798496.665
[15:29:58.496682]   55798496.682
[15:29:58.497096]   55798497.096
[15:29:58.498621]   55798498.621
4
16.05.2019, 18:32
1 ответ

printfпринимает один гарантированный параметр, а затем ряд дополнительных параметров в зависимости от того, что вы передаете. Что-то вроде этого:

printf '%07.2f' 5

превращается в:

0005.00

Первый параметр, называемый "format", присутствует всегда. Если он не содержит строк %, он просто печатается. Таким образом:

printf Hello

производит просто Hello(, в частности, без завершающей новой строки echo, которая будет добавлена ​​в режиме по умолчанию ). Ожидая, что ваш пример сработает, вы были введены в заблуждение своим предыдущим (неосознанным )злоупотреблением этим фактом; поскольку вы передавали только строки без %в format, с точки зрения printfвы продолжали просить его вывести вещи, которые не требуют подстановок, поэтому он в значительной степени функционировал как echo -ne.

Если вы хотите сделать это правильно , вы, вероятно, захотите начать формировать печатные строки со встроенными возможностями подстановки printf. Подобные строки появляются во всем моем коде:

printf '%20s: %6d %05d.%02d%%' "$key" $val $((val/max)) $((val*100/max%100))

Если вы хотите, чтобы именно то, что вы сейчас делаете, работало, вам нужно echo -ne, так что:

TEST="contains % percent"
echo -ne "${TEST}\n"

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

TEST="contains % percent"
echo -e "$TEST"
4
27.01.2020, 20:44

Теги

Похожие вопросы