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, в котором эта функция была реализована

Другие вопросы по тегам