Bash: Как использовать расширение параметра оператора ${параметр @ оператор}?
Я гуглил и пробовал так много вещей и никогда не мог заставить что-либо работать с ${parameter@operator}. Все, что я нахожу, - больше ссылок на ту же документацию. Поэтому я думаю, что правильный ответ с практическими примерами был бы очень полезен для его понимания.
В документации сказано:
$ {Параметр @ оператор}
Расширение - это либо преобразование значения параметра, либо информация о самом параметре в зависимости от значения оператора. Каждый оператор представляет собой одну букву:
Q
Расширение - это строка, представляющая собой значение параметра в кавычках в формате, который можно повторно использовать в качестве входных данных.
Это также говорит о цитировании:
3.1.2 Цитирование
Цитирование используется для удаления специального значения определенных символов или слов в оболочке.
Поэтому я рассуждаю так: вывод этого (специальный символ $):
a="To be reused as an input string, \$0 needs to be quoted"
echo ${a@Q}
должно быть так (между "", "\" удаляется, поэтому необходимо снова заключить в кавычки, чтобы использовать в качестве входных данных):
To be reused as an input string, \$0 needs to be quoted
но я получаю:
bash: ${a@Q}: bad substitution
Я пробовал разные комбинации:
${a@q}, "${a@Q}", a='To be reused as an input string, $0 needs to be quoted'
но безрезультатно.
На самом деле, любые операторы, которые я пытаюсь использовать, всегда выдают ошибку неправильной замены. Это, кажется, очень неясные черты bash. Я пропустил из этого поста около получаса попыток, каждая из которых была более извращенной, чем предыдущая!
2 ответа
Для тех, кто прибывает сюда в поисках информации о другом операторе расширения, вот краткий список доступных символов расширения и их эффектов.
${varname@Q}
возвращает строку с одиночным Q и все экранированные специальные символы (такие как \n, \t и т. д.).
Примеры:
$ foo="one\ntwo\n\tlast"
$ echo "$foo"
one\ntwo\n\tlast
$ echo ${foo@Q}
'one\ntwo\n\tlast'
${varname@E}
возвращает строку со всеми экранированными символами E xpanded (например, \n -> новая строка).
Примеры:
$ foo="one\ntwo\n\tlast"
$ echo "${foo}"
one\ntwo\n\tlast
$ echo "${foo@E}"
one
two
last
${varname@P}
возвращает строку, которая показывает, как будет выглядеть переменная, если бы она использовалась в качестве переменной Pompt (т.е. PS1, PS2, PS3)
Пример:
$ bar='host: \h'
$ echo ${bar@P}
host: myhost1
(Существует много других escape-последовательностей, которые можно применять в переменных приглашения. См. Документацию bash.)
${varname@A}
возвращает строку, которая может быть использована для A ssign переменной с ее существующим именем, значением и declare
варианты, если таковые имеются.
Пример:
$ foo="test1"
$ echo ${foo@A}
foo='test1'
$ declare -i foo=10
$ echo "${foo@A}"
declare -i foo='10'
${varname@a}
возвращает строку, перечисляющую атрибуты A переменной.
Пример:
$ declare -ir foo=10
$ echo ${foo@a}
ir
(Доступны следующие варианты объявления: -r
только для чтения, -i
целое число, -a
массив, -f
функция, -x
экспортируемый.)
Извините, я не просматривал Stack должным образом, здесь есть пример использования:
Как отобразить файл с несколькими строками как одну строку с escape-символами (\n)
$ foo=$(<file.txt)
$ echo "${foo@Q}"
$'line1\nline2'
Кроме того, у меня нет bash 4.4, в котором эта функция была реализована