Dan*_*der 3 shell quoting escape-characters
我只是(再次)为此而挣扎:
# only in bash
NORM=$'\033[0m'
NORM=$'\e[0m'
# only in dash
NORM='\033[0m'
# only in bash and busybox
NORM=$(echo -en '\033[0m')
Run Code Online (Sandbox Code Playgroud)
目标是在字符串中包含特殊字符,不仅用于输出使用echo
,还用于管道到 cli 工具等。
在上面的特定用例中,使用$(tput ...)
可能是最好的方法,但我要求一个通用的转义解决方案,对外部工具的要求最低,但兼容性最高。
通常,我会使用类似[ -z "$BASH_VERSION" ]
但的条件帮助自己
你想要的是"$(printf ...)"
. Stephane 已经写了一篇关于printf
vsecho
的精彩公开,更多的是一篇文章而不是单纯的答案,所以我不会在这里重复整个事情。与当前问题相关的主旨是:
我还要补充一点,我花了很长时间(好吧,仅仅几个星期)才从 切换到echo
,因为我已经习惯echo
并认为printf
这会很复杂。(所有这些%
标志是关于什么的,嗯?)事实证明,printf
实际上非常简单,echo
除了在末尾带有换行符的固定文本之外,我不再为任何事情而烦恼。
Printf变得简单
有大量的选择printf
。您可以将数字打印到精确的特定小数位。您可以打印多个字段,每个字段都具有指定的固定宽度(或最小宽度或最大宽度)。您可以创建一个包含字符序列的 shell 字符串变量,\t
或者\n
将这些字符序列解释为制表符和换行符来打印。
您可以做所有这些事情,并且您应该知道它们是可能的,以便您可以在需要时查找它们,但在大多数情况下,您只需要了解以下内容:
printf
将一个名为“format”的字符串作为它的第一个参数。格式字符串可以指定如何处理进一步的参数(即如何格式化它们)。进一步的参数,如果在格式参数中根本没有引用*,将被忽略。
由于字母数字字符(和其他字符)可以嵌入格式参数中并按原样打印,它看起来可能与printf
做同样的事情,echo -n
但出于某种未知原因,它忽略了除第一个参数之外的所有内容。事实并非如此。
例如,尝试printf some test text
。在这个例子some
中实际上被当作format,并且因为它不包含任何特殊的东西并且不告诉printf
如何处理其余的参数,它们被忽略,你得到的只是some
.
%
后跟需要在格式字符串中使用的特定字母( 的第一个参数printf
)来指定后续参数包含的数据类型。 %s
表示“字符串”,是您最常使用的。
\n
或\t
在格式内分别转换为换行符和制表符。
这就是您printf
高效使用所需的全部内容。有关一些非常简单的说明性示例,请参阅以下代码块。
$ var1="First"
$ var2="Second"
$ var3="Third"
$ printf "$var1" "$var2" "$var3" # WRONG
First$ # Only the first arg is printed, without a trailing newline
$
$ printf '%s\n' "$var1" # %s means that the next arg will be formatted as a literal string with any special characters printed exactly as-is.
First
$
$ printf '%s' "$var1" "$var2" "$var3" # When more args are included than the format calls for, the format string is reused. This example is equivalent to using '%s%s%s' as the format.
FirstSecondThird$ # All three args were printed; no trailing newline.
$
$ printf '%s\t%s\t%s\n' "$var1" "$var2" "$var3"
First Second Third # Tab separation with trailing newline. This format is very explicit about what to do with three arguments. Now see what happens if four are used:
$ var4="Fourth"
$ printf '%s\t%s\t%s\n' "$var1" "$var2" "$var3" "$var4"
First Second Third # The specified format is reused after the three expected args,
Fourth # so this line has two trailing tabs.
$
$ printf '%s\n' "$var1" "$var2" "$var3" # This format reuse can be used to advantage in printing a list, for example.
First
Second
Third
$
$ printf '%s\t' "$var1" "$var2" "$var3" ; printf '\n' # Here is a dual command that could have args added without changing the format string...
First Second Third
$ printf '%s\t' "$var1" "$var2" "$var3" "$var4" ; printf '\n'
First Second Third Fourth # ...as you can see here.
$ # It does print a trailing tab before the newline, however.
Run Code Online (Sandbox Code Playgroud)
* 当然,如果您包含单个参数格式说明符序列,例如%s
,您的整个格式字符串将根据需要重复使用多次,以处理提供的所有参数。请参阅示例。