我想将printf
的输出与格式存储在一个变量中,但由于某种原因它会删除格式。
这是正确的输出
$ printf "%-40s %8s %9s %7s" "File system" "Free" "Refquota" "Free %"
File system Free Refquota Free
现在格式化已经消失了
$ A=$(printf "%-40s %8s %9s %7s" "File system" "Free" "Refquota" "Free %")
$ echo $A
File system Free Refquota Free %
答案 0 :(得分:5)
这是因为您没有引用该变量。如果这样做,格式将完美显示:
echo "$A" #although $a would be best, uppercase vars are not good practise
也就是说,您的var=$(printf )
方法完全没问题,您只是echo
无法正常使用。
您可能想知道原因。在Why does my shell script choke on whitespace or other special characters?
中找到它为什么我需要写
"$foo"
?没有引号会发生什么?
$foo
并不意味着“获取变量foo
的值”。它的意思是 更复杂的事情:
- 首先,取变量的值。 *场分裂:治疗 该值作为以空格分隔的字段列表,并构建 结果清单。例如,如果变量包含
foo * bar
然后,此步骤的结果是3个元素的列表foo
,*
,bar
。
- 文件名生成:将每个字段视为glob,即作为通配符模式,并将其替换为与此匹配的文件名列表 图案。如果模式不匹配任何文件,则保留 修改。在我们的示例中,这导致列表包含
foo
, 以下是当前目录中的文件列表,最后是bar
。如果当前目录为空,则结果为foo
,*
,bar
。请注意,结果是字符串列表。有两种情况 shell语法:列表上下文和字符串上下文。场分裂和 文件名生成仅发生在列表上下文中,但大多数情况下都是如此 时间。双引号分隔字符串上下文:整体 双引号字符串是单个字符串,不能拆分。 (例外:
"$@"
扩展到位置参数列表,例如"$@
是 如果有三个位置,则相当于"$1" "$2" "$3"
参数。见What is the difference between $* and $@?)使用
$(foo)
或`foo`
命令替换也是如此。在旁注中,请勿使用`foo`
:其引用规则是 奇怪的和不可移植的,所有现代的shell支持$(foo)
除了具有直观的引用规则外,它是完全等效的。算术替换的输出也经历相同的 扩展,但这通常不是一个问题,因为它只包含 不可扩展的字符(假设
IFS
不包含数字或-
)。有关详细信息,请参阅When is double-quoting necessary? 你可以省略引号的情况。
除非你的意思是发生这一切,否则请记住 总是在变量和命令替换周围使用双引号。做 注意:遗漏引号不仅会导致错误而且会导致错误 security holes
答案 1 :(得分:4)
echo
将按顺序打印每个参数,以一个空格分隔。您将一堆不同的参数传递给echo
。
简单的解决方案是引用$A
:
A=$(printf "%-40s %8s %9s %7s" "File system" "Free" "Refquota" "Free %")
echo "$A"