简体   繁体   English

如何对现有的bash变量进行ANSI C引用?

[英]How can I do ANSI C quoting of an existing bash variable?

I have looked at this question , but it does not cover my use case. 我看过这个问题 ,但它不包括我的用例。

Suppose I have the variable foo which holds the four-character literal \\x60 . 假设我有变量foo ,它包含四个字符的文字\\x60

I want to perform ANSI C Quoting on the contents of this variable and store it into another variable bar . 我想对此变量的内容执行ANSI C Quoting并将其存储到另一个变量bar

I tried the following, but none of them achieved the desired effect. 我尝试了以下,但没有一个达到预期的效果。

bar=$'$foo'   
echo $bar     
bar=$"$foo"     
echo $bar       

Output: 输出:

$foo
\x61

Desired output (actual value of \\x61 ): 期望的输出( \\x61实际值):

a

How might I achieve this in the general case, including non-printable characters? 如何在一般情况下实现此目的,包括不可打印的字符? Note that in this case a was used just as an example to make it easier to test whether the method worked. 请注意,在这种情况下a仅使用a作为示例,以便更容易测试方法是否有效。

By far the simplest solution, if you are using bash : 到目前为止,最简单的解决方案,如果你使用bash

printf %b "$foo"

Or, to save it in another variable name bar : 或者,将其保存在另一个变量名称bar

printf -v bar %b "$foo"

From help printf : 来自help printf

In addition to the standard format specifications described in printf(1) and printf(3), printf interprets: 除了printf(1)和printf(3)中描述的标准格式规范外,printf还解释:

  %b expand backslash escape sequences in the corresponding argument %q quote the argument in a way that can be reused as shell input %(fmt)T output the date-time string resulting from using FMT as a format string for strftime(3) 

There are edge cases, though: 但是有边缘情况:

\\c terminates output, backslashes in \\', \\", and \\? are not removed, and octal escapes beginning with \\0 may contain up to four digits \\ c终止输出,\\',\\“和\\?中的反斜杠不会被删除,以\\ 0开头的八进制转义可能包含最多四位数字

The best method I know is 我知道的最好的方法是

  y=$(printf $(echo "$foo"|sed 's/%/%%/g'))

As mentioned in the comments, this trims trailing newlines from $foo . 正如评论中所提到的,这会削减$foo尾随换行符。 To overcome this: 要克服这个:

moo=$(echo "${foo}:end"|sed 's/%/%%/g')
moo=$(printf "$moo")
moo=${moo%:end}
# the escaped string is in $moo
echo "+++${moo}---"

I just found out that I can do this. 我发现我能做到这一点。 Edited based on comments. 根据评论编辑。

bar=$( echo -ne "$foo" )

The following works: 以下作品:

 eval bar=\$\'$x\'

The command bar=$'\\x61' has to be constructed first, then eval evaluates the newly built command. 必须首先构造命令栏= $'\\ x61',然后eval评估新构建的命令。

Sample of conversion via shell. 通过shell转换的示例。 Problem, the code is octal using \\0nnn and hexdecimal (not on all shell) using \\xnn (where n are [hexa]digit) 问题,该代码是使用八进制\\0nnn使用和hexdecimal(不是在所有壳) \\xnn (其中n是[六]位)

foo="\65"
print "$( echo "$foo" | sed 's/\\/&0/' )"

5

with awk, you could certainly convert it directly 使用awk,你当然可以直接转换它

Since bash 4.4 there is a variable expansion to do exactly that: 从bash 4.4开始,有一个变量扩展可以做到这一点:

$ foo='\x61';     echo "$foo" "${foo@E}"
\x61 a

To set another variable use: 要设置另一个变量:

$ printf -v bar "${foo@E}";     echo "$bar"
a

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM