Bash: How to use operator parameter expansion ${pa

2020-02-11 01:03发布

问题:

I've googled and tried so many things and never could get anything to work with ${parameter@operator}. All I find is more links to the same documentation. So I think a proper answer with practical examples would be very helpful to its understanding.

The documentation says:

${parameter@operator}

The expansion is either a transformation of the value of parameter or information about parameter itself, depending on the value of operator. Each operator is a single letter:

Q
The expansion is a string that is the value of parameter quoted in a format that can be reused as input.

It also says about quoting:

3.1.2 Quoting
Quoting is used to remove the special meaning of certain characters or words to the shell.

So my reasoning is that the output of this (special character $):

a="To be reused as an input string, \$0 needs to be quoted"
echo ${a@Q}

should be this (between "", the '\' is removed, so needs quoting again to be used as an input):

To be reused as an input string, \$0 needs to be quoted

but I get:

bash: ${a@Q}: bad substitution

I tried different combinations of:

${a@q}, "${a@Q}", a='To be reused as an input string, $0 needs to be quoted'

to no avail.

Actually, any operators I try to use always yields the bad substitution error. Those seems to be very obscure features of bash. I've omitted from this post about half an hour of attempts each one more twisted than the previous!

回答1:

For those who arrive here looking for information on a different expansion operator, here's a quick list of the available expansion characters and their effects.

${varname@Q} returns a single-Quoted string with any special characters (such as \n, \t, etc.) escaped.

Examples:

$ foo="one\ntwo\n\tlast"
$ echo "$foo"
one\ntwo\n\tlast

$ echo ${foo@Q}
'one\ntwo\n\tlast'

${varname@E} returns a string with all the escaped characters Expanded (e.g. \n -> newline).

Examples:

$ foo="one\ntwo\n\tlast"
$ echo "${foo}"
one\ntwo\n\tlast

$ echo "${foo@E}"
one
two
        last

${varname@P} returns a string that shows what the variable would look like if it were used as a Prompt variable (i.e. PS1, PS2, PS3)

Example:

$ bar='host: \h'
$ echo ${bar@P}
host: myhost1

(There are many more escape sequences that can be applied in prompt variables. See the bash documentation.)

${varname@A} returns a string that can be used to Assign the variable with its existing name, value, and declare options if any.

Example:

$ foo="test1"
$ echo ${foo@A}
foo='test1'

$ declare -i foo=10
$ echo "${foo@A}"
declare -i foo='10'

${varname@a} returns a string listing the Atributes of the variable.

Example:

$ declare -ir foo=10
$ echo ${foo@a}
ir

(The available declare options are: -r readonly, -i integer, -a array, -f function, -x exportable.)



回答2:

Sorry, I didn't browse Stack properly, there is an example use here:

How to display a file with multiple lines as a single string with escape chars (\n)

$ foo=$(<file.txt)
$ echo "${foo@Q}"
$'line1\nline2'

Plus, I don't have bash 4.4 in which the feature was implemented < sigh >