Вот мое решение со стандартным набором инструментов Linux.
$ foo="This is a line feed
And e acute:é with a grinning face 😀."
$ echo "$foo"
This is a line feed
And e acute:é with a grinning face 😀.
$ eval "$(printf '%s' "$foo" | sed 's/^/printf "/;s/�*\([0-9]*\);/\$( [ \1 -lt 128 ] \&\& printf "\\\\$( printf \"%.3o\\201\" \1)" || \$(which printf) \\\\U\$( printf \"%.8x\" \1) )/g;s/$/\\n"/')" | sed "s/$(printf '\201')//g"
This is a line feed
And e acute:é with a grinning face ?.
Вы видите, что он работает для всех видов экранированных символов, даже для перевода строки, e острый (é), который является 2-байтовым UTF-8, и даже для новых смайликов, которые находятся в расширенной плоскости (4-байтовый юникод).
Эта команда работает ТАКЖЕ с дефисом, который представляет собой обрезанную оболочку (оболочка по умолчанию в Ubuntu), а также совместим с панелью bash и оболочками, подобными пеплу, используемому Synology.
Если вы не против использовать bash и отказаться от совместимости, вы можете сделать это намного проще.
Используемые биты должны быть в любом приличном Linux-боксе (или OS X?)
- который
- printf (GNU и встроенный)
- GNU sed
- eval (встроенная оболочка)
В версии только для bash не требуется ни GNU printf.