如何将printf的输出存储在变量中?

时间:2015-07-08 13:06:52

标签: linux bash printf echo

我想将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 %

2 个答案:

答案 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"