【问题标题】:Formatting output with printf: truncating or padding使用 printf 格式化输出:截断或填充
【发布时间】:2016-03-21 00:02:15
【问题描述】:

我想产生以下输出:

> Avril Stewart  99  54
> Sally Kinghorn 170 60
> John Young     195 120
> Yutte Schim... 250 40

如您所见,少于 14 个字符的名称用空格填充。长度超过 15 个字符的名称将被截断:“Yutte Schimmelpenninck”截断为“Yutte Schim...”。

这是我尝试实现的(变量$name$height$weight 是从文件中提取的,并且循环对每个文件数据运行printf 命令):

printf '%-14s -%3s -%3s\n' "$name" "$height" "$weight"
> Avril Stewart  99  54
> Sally Kinghorn 170 60
> John Young     195 120
> Yutte Schimmelpenninck 250 40

printf 单行是理想的解决方案。

什么代码会产生第一个输出块?

【问题讨论】:

  • 数据从何而来?
  • 你确定这是你尝试的吗?我认为您的格式字符串会在字段之间产生-
  • 这些字段是从一个未知长度的文件中读入的。实际发出的命令是 printf '%-14s -%3s -%3s\n' $name $weight $height。

标签: bash awk printf output formatted


【解决方案1】:

在您的printf 命令之前,您要检查名称是否超过 14 个字符,如果是,则截断它并将最后三个字符替换为点。此命令执行此操作:

(( ${#name} > 14 )) && name="${name:0:11}..."

它将name 替换为其前十一个字符并附加...

您还必须修复 printf 格式字符串:而不是

'%-14s -%3s -%3s\n'

应该是的

'%-14s %-3s -%-3s\n'

或者你会得到这样的结果

Avril Stewart  - 99 - 54

也许这只是一个错字,因为您的示例输出没有连字符。

总而言之:

$ name='Avril Stewart'; weight=99; height=54
$ (( ${#name} > 14 )) && name="${name:0:11}..."
$ printf '%-14s %-3s %-3s\n' "$name" $weight $height
Avril Stewart  99  54
$ name='Sally Kinghorn'; weight=170; height=60
$ (( ${#name} > 14 )) && name="${name:0:11}..."
$ printf '%-14s %-3s %-3s\n' "$name" $weight $height
Sally Kinghorn 170 60
$ name='Yutte Schimmelpeninck'; weight=250; height=40
$ (( ${#name} > 14 )) && name="${name:0:11}..."
$ printf '%-14s %-3s %-3s\n' "$name" $weight $height
Yutte Schim... 250 40

所以如果你从一个文件中读取这个,例如逗号分隔,你最终会得到一个这样的循环:

while IFS=, read -r name weight height; do
    (( ${#name} > 14 )) && name="${name:0:11}..."
    printf '%-14s %-3s %-3s\n' "$name" $weight $height
done < inputFile

导致

Avril Stewart  99  54
Sally Kinghorn 170 60
John Young     195 120
Yutte Schim... 250 40

我认为在单行中这是不可能的。我尝试了三元运算符并尝试了类似

printf '%s\n' $(( ${#name} > 14 ? "${name:0:11}..." : "$name" ))

但这里的问题是它只适用于整数,而字符串在算术上下文中扩展为零。

【讨论】:

    【解决方案2】:

    一个更惯用的awk 版本将是

    $ awk        '{v=$1 FS $2} 
      length(v)>14{v=substr(v,1,11)"..."}
                  {printf "%-15s %-3d %-3d\n",v,$3,$4}' file     
    
    Avril Stewart  99  54 
    Sally Kinghorn 170 60 
    John Young     195 120
    Yutte Schim... 250 40
    

    如果您删除 %-3d 中的 - 符号,数字将照常右对齐,但这就是您要求的格式。

    【讨论】:

      【解决方案3】:

      这是部分答案——忽略最后的“...”:

      awk '{printf "%-14.14s %-3d %-3d\n",$1 FS $2,$3,$4}'
      

      %-14.14s 对名称进行填充 + 截断格式

      【讨论】:

      • 这是我需要使用 __git_ps1 的可选 printf 参数截断的内容。请注意,您可以在不使用 %.14s 填充的情况下截断为 14,我选择跳过“...”,因为我的目标是限制我的 PS1 长度。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-08-09
      • 1970-01-01
      • 2020-03-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多