печать строки "canonical print-escaped form"

Я пытаюсь написать функцию, я назову ее escape , которая будет вести себя следующим образом:

 % IFS=$' \t\n\000' % escape FOO $IFS FOO=$' \t\n\000' 

Другими словами, escape принимает два аргумента, а затем, беря первое имя переменной, он выводит строку zsh исходный код, в котором переменной этого имени присваивается $'' -quoted, "canonically print «escaped», так что при оценке этой строки исходного кода переменная, названная первым аргументом, будет иметь второй аргумент как его значение. (Я уверен, что это было так ясно, как грязь, поэтому я приведу больше примеров того, как escape должен вести себя в конце этого поста.)

Вот неполная реализация функции escape :

 escape () { local varname=$1 local value="$2" print -n "$varname=\$'" # ??? print "'" } 

Недостающая часть (обозначенная ??? ) означает, что содержимое $value «канонически print ». Квалификатор «канонический» необходим, потому что есть много символов, для которых есть хотя бы несколько представлений, которые print распознает их как. Например, print знает \n также как \012 и как \CJ . В этом случае \n – каноническая форма. В общем случае стандартные escape-последовательности \n , \r , \t и \t Д. Являются каноническими формами для их соответствующих символов. Стандартная форма отображения печатных символов ASCII (например, A , = , 9 ) является канонической. Для остальных символов, если есть выбор представления, я бы выбрал восьмеричную форму как каноническую (по крайней мере, до \177 ; я не уверен, как $'' имеет дело с более высокими кодами), но это предпочтение не является сильным.

Конечно, я не хочу видеть код для реализации этой функции «с нуля». Скорее, я надеюсь, что утилита уже существует для выполнения этого перевода из байтов в текстовое представление с print .

Любые указатели были бы высоко оценены!


Вот еще несколько примеров escape в действии (гипотетически):

 % escape HELLO $( echo 'hello world' ) HELLO=$'hello world\n' % escape SUBSEP $( perl -e 'print $;' ) SUBSEP=$'\034' % abc=$'\141\012\142\012\143\012' % print -n $abc a b c % escape ABC $abc ABC=$'a\nb\nc\n' 

Я думаю, что для флага расширения параметра q , в qqqq варианта qqqq .

 FOO=${(qqqq)IFS} 

Таким образом, вы можете написать свою функцию таким образом (используя флаг P для расширения параметра с именем $2 ):

 escape () { print -r -- "$1=${(Pqqqq)2}" }