"выявление" скрытых / управляющих "кодов" в строках в bash
В Python есть очень удобная функция: repr (), которая при применении к строке, содержащей пустые символы, выведет представление этой строки, которое не может привести к неправильной интерпретации человеком фактического содержимого строки.
например:
$ python -c "print repr(r'''abcde\rfghi\tjklmn\nopqr\bstuv\fwxyz''')"
'abcde\\rfghi\\tjklmn\\nopqr\\bstuv\\fwxyz'
Как я могу сделать то же самое в bash с printf?
Идеальный инструмент / трюк, который я ищу, буквально напечатает
'abcd\refjh\bijk'
для команды
printf "abcd\refjh\bijk" | <something>
Цель этого состоит в том, чтобы улучшить инструмент тестирования, который печатает различия между двумя строками:
http_response_code=$(curl -s --head http://httpbin.org/ | head -1) # will put "HTTP/1.1 200 OK\r" in $http_response_code
assert_equal "HTTP/1.1 200 OK" "$http_response_code"
> failed: strings do not match
> expected: 'HTTP/1.1 200 OK'
> actual: 'HTTP/1.1 200 OK'
Как видите, текущая реализация позволила пользователю невежественно и совсем запутаться в причинах сбоя.
В идеале я хотел бы получить следующий вывод:
> failed: strings do not match
> expected: 'HTTP/1.1 200 OK'
> actual: 'HTTP/1.1 200 OK\r'
Текущие попытки:
printf $'\a\b\e\E\f\n\r\t\v\\\'\"' | cat -A
echo $'\a\b\e\E\f\n\r\t\v\\\'\"' | cat -A | sed -r '$!{ N;s/\$\n/\\n/;t sub-yes;:sub-not;P;D;:sub-yes;}'
printf $'\a\b\e\E\f\n\r\t\v\\\'\"' | od -c
1 ответ
%q
спецификатор формата приближается к вашему идеальному выводу:
$ printf '%q' "abcd\refjh\bijk"
abcd\\refjh\\bijk
Это выводит строку, которая эквивалентна вашей идее; например, оболочка лечит '\r'
а также \\r
точно так же. Также,
$ printf '%q' $'\a\b\e\E\f\n\r\t\v\\\'\"'
$'\a\b\E\E\f\n\r\t\v\\\'"'
Выходные данные используют формат цитирования ANSI, чтобы показать строку, содержащую фактические непечатаемые символы.
Для принудительного цитирования ANSI для строк, которые содержат только печатные символы, вы можете добавить непечатаемый символ в конец строки, отформатировать его, а затем удалить добавленный символ.
$ var="My string"
$ printf -v var '%q' "$var"$'\n' # Add a newline
$ [[ $var =~ \$\'(.*)\\n\' ]] && var="\$'${BASH_REMATCH[1]}'"
$ echo "$var"