"выявление" скрытых / управляющих "кодов" в строках в 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"
Другие вопросы по тегам