Що є зворотним відлунням -e?


13

Якщо у мене є рядок з недрукованими символами, новими рядками чи вкладками, чи є спосіб, щоб я echoнадрукував цей рядок і показав коди для цих символів (наприклад, \nдля нового рядка, \bдля зворотної області)?


2
ви можете скористатися командою printf, дивіться man printf
PersianGulf

12
e- ohce* rimshot *
Девід Річербі

3
printf '%q' "$str"буде друкувати рядок, що уникнув. Я не додаю це як відповідь, оскільки це не та сама форма втечі, яка echo -eвикористовує - скоріше, це має бути безпечно для огляду - але (1) це досить добре, якщо ваша мета - читабельність людини, (2) це достатньо добре, якщо ваша мета - безпечне генерування оболонок, і (3) echo -e- Evil And Wrong так чи інакше (якщо ви прочитаєте специфікацію POSIX, ви побачите, що printf є кращим способом виконувати форматування рядків, і echo -eце не гарантується базовим POSIX на всі).
Чарльз Даффі

Відповіді:


7

Існує маса способів зробити це. Самий портативний два , що я знаю це , sedі od- вони обидва стандарти POSIX.

printf '\n\r\b\t\033[01;31m' | sed -n l

Це схоже на ... readстиль втечі - C-стиль.

ВИХІД

$
\r\b\t\033[01;31m$

od трохи настроюється ...

printf '\n\r\b\t\033[01;31m' |
od -v -w12 -t c -t a -A n

 \n  \r  \b  \t 033   [   0   1   ;   3   1   m
 nl  cr  bs  ht esc   [   0   1   ;   3   1   m

Якщо ви хочете знати, які всі ці параметри ви можете шукати man od, але я вказую, що мені потрібно два типи втечі - -t cзворотна косою рисою та -t aназвані символи. -wПараметр , який використовується вище, не є POSIX-вказівки.

І ось невелика функція оболонки, яка переносимо друкує восьмеричні значення кожного байта в його аргументах - що, звичайно, odможе справлятися і з -t o:

proctal() (LC_ALL=C
    for a do while [ -n "$a" ] 
    do printf %o\\n "'$a"
    a=${a#?}; done; done)  

Це просто. Це трохи складніше. printf -qОднак він повинен мати можливість робити те, що може реалізувати конкретна оболонка .

bsq() (set -f; export LC_ALL=C IFS=\'
    for a do q=${a##*\'}; printf \'
    [ -n "${a#"$q"}" ] &&
        printf "%s'\''" ${a%\'*}
    printf "%s'\n'''''\n" "$q"; done |
    sed -n "/'''''"'/!H;1h;//!d;$!n;x;l' |
    sed -e :n -e '/\\$/N;s/.\n//;tn
        s/\([^\\]\\\(\\\\\)*\)\([0-9]\)/\10\3/g
        s/\\\\'"''/\\\\''"'/g;s/$$//'
)

Використовуючи рядок прикладу з попереднього з невеликим додатковим:

bsq "$(printf '\n\r\'\''b\t\033[01;31m')"

ВИХІД

'\n\r\\'\''b\t\0033[01;31m'

Це лише трохи інакше. Ви можете помітити, що є додаткова 0та додаткова \bрізка різка. Це дозволяє легко перекласти аргумент readабо %b printfаргумент. Наприклад:

i=0
until [ $((i=$i+1)) -gt 5 ]
do touch "\%$i$(printf 'hey\b \t;\n\033 ')"
done   #just for ugly's sake

bsq * | eval "
    printf '<%b>\n' $(tr \\n \ )
" | tee /dev/fd/2 |
sed -n l

ВИХІД

<\%1he  ;
>
<\%2he  ;
>
<\%3he  ;
>
<\%4he  ;
>
<\%5he  ;
>
<\\%1hey\b \t;$
\033 >$
<\\%2hey\b \t;$
\033 >$
<\\%3hey\b \t;$
\033 >$
<\\%4hey\b \t;$
\033 >$
<\\%5hey\b \t;$
\033 >$

@ StéphaneChazelas Він все одно буде робити лише однобайтові символи, але, сподіваємось, зараз його менше шансів.
mikeserv

1
Дозвольте мені дістати вас до позначки 10k :)
Рамеш

Woohoo !!!!!!!!!
slm

@slm - дозвольте здогадатися .. Вам дуже сподобався proctal?
mikeserv

@ StéphaneChazelas - у вас є якісь думки bsq()- чи щось не вистачає? Я запитую, тому що я не зовсім впевнений у відхиленнях від нахилу.
mikeserv

12

Коли ви виймете -eперемикач на echo, в bash, та за умови, що xpg_echoпараметр не ввімкнено, він повинен друкувати рядки не більше ніж їх оригінальний текст. Так \nі \tпоказало б це буквально так.

Приклад

$ echo "hi\t\tbye\n\n"
hi\t\tbye\n\n

$ echo -e "hi\t\tbye\n\n"
hi      bye

Ви також можете використовувати printfвбудований в команду ksh93, zshабо bashдля надувати і це.

$ printf "%q\n" "$(echo -e "hi\t\tbye\n\nbye")"
$'hi\t\tbye\n\nbye'

( bashвихідний показаний вище. Існують деякі варіанти залежно від оболонки).

уривок зhelp printf вbash

%q цитуйте аргумент таким чином, що його можна повторно використовувати як введення оболонки


1
Це не printf %qщо - х усікань тягнеться \nз, це $()вихід захоплення , що роздягає їх.
екатмур

@ecatmur - дякую, що я написав це пізно вночі і не намагався його налагоджувати далі. Ви будете вірні, саме їх знищить. Ось причина, чому: unix.stackexchange.com/questions/17747/…
slm

... так чи інакше, запускати printfвсередину підзаголовка, щоб захопити її вихід, є нерозумним, оскільки printf -v varnameвиводить висновок безпосередньо в змінну, не задіяна підкатегорія.
Чарльз Даффі

@CharlesDuffy - Я не слідкую за тобою, я не запускаюсь printfв нижній підрозділ , я бігав echoв одній, просто для того, щоб продемонструвати, що ти можеш взяти спеціальний вихідний символ echoі перетворити його назад у втечене позначення.
slm

@slm, це була відповідь на перший коментар (ну, код, на який відповів перший коментар), а не код, як я його знайшов зараз. Якщо я зробив щось неточне про стан попереднього редагування, мої вибачення.
Чарльз Даффі

5

Ви можете використовувати щось на кшталт,

$ cat filename
Ramesh is testing
New Line        is

Тепер ви можете зробити щось на кшталт,

$ cat -A filename

Вихідні дані

Ramesh is testing$
New Line ^Iis $

Ще одне загальне тестування без файлів -

$ echo Hello$'\t'world. | cat -A

Наведена вище команда дає результат у вигляді,

Hello^Iworld.$

Список літератури


4
Або, в не-GNU реалізація кішки, наприклад , MacOS / X, візьміть свою кішку до ветеринара ... кішка -v
Tink

3

З zsh, Є (q), (qq), (qqq), (qqqq)змінна прапори розширення , які можуть процитувати змінні різними способами:

$ a=$'a b\nba\bc\u00e9\0'

$ printf '%s\n' $a
a b
bcé

$ printf %s $a | od -vtc
0000000   a       b  \n   b   a  \b   c 303 251  \0
0000013

$ printf '%s\n' ${(q)a}
a\ b$'\n'ba$'\b'cé$'\0'

$ printf '%s\n' ${(qq)a}
'a b
bcé'

$ printf '%s\n' ${(qqq)a}
"a b
bcé"

$ printf '%s\n' ${(qqqq)a}
$'a b\nba\bcé\0'

$ (){local LC_ALL=C; print -r -- ${(qqqq)a}}
$'a b\nba\bc\303\251\0'

У вашому випадку ви, мабуть, хочете одне з останніх двох.


1

od -cбуде друкувати звичайні символи як правило, але спеціальні символи (вкладка, новий рядок тощо) та недруковані символи як printfкод виходу.

Так:

$ echo -e asdf\\nghjk\\003foo | od -c -An
   a   s   d   f  \n   g   h   j   k 003   f   o   o  \n

-AnКаже odне виводиться адреса.


-1

Використовуйте printfкоманду. Наприклад:

printf "Hello\nthis is my line

виведе

Hello
this is my line

1
Це ж , як echo -e, я дивлюся на реверсі .
вр

Ви можете навести конкретний приклад?
Lazuardi N Putra
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.