如何在tcl中以统一的方式显示输出

时间:2011-09-12 07:03:16

标签: tcl

我对format命令有疑问。我的输出是一种群集,不像下面那样不统一

    24-04-2011    16:07  <DIR>  Administrator 
    15-05-2011 16:05 <DIR> confuser 
    01-02-2011   20:57  <DIR>  Public 

我应该怎样做才能以正确和统一的方式显示输出。一切都在同一列的开头。像这样:

是的,我使用了这个命令puts [format {%-s %-4s %-8s} $user\t $date\t $time],它给我的输出如下:

Administrator 15-05-2011 16:05 
confuser 01-02-2011 20:57 
Public 29-01-2011 19:28 
TechM 30-04-2011 09:47

接收的输出是根据第一个字符串中出现的字母数,例如administrator confuser public techm。所以我需要知道的是如何获得一个不考虑第一个字符串长度的输出并给出一个合适的统一圆柱输出。

3 个答案:

答案 0 :(得分:7)

廉价的黑客方法是在输出字符串中使用制表符作为分隔符(“\t”而不是“”)。这适用于少量变化,但不会处理大范围的变化(或当前终端/编辑器标签宽度周围的小变化)。

要正确完成工作,您需要先获取要打印的所有概念行的列表(即数据但尚未格式化)。然后,遍历每一行,计算每个字段所需的宽度,在整个数据集中取最大值。然后,您可以配置format的格式字符串。这是一个例子(对于Tcl 8.5),其中所有内容都被格式化为字符串:

proc printColumnarLines {lines} {
    foreach fields $lines {
        set column 0
        foreach field $fields {
            set w [string length $field]
            if {![info exist width($column)] || $width($column) < $w} {
                set width($column) $w
            }
            incr column
        }
    }
    foreach fields $lines {
        set column 0
        foreach field $fields {
            puts -nonewline [format "%-*s " $width($column) $field]
            incr column
        }
        puts ""; # Just the newline please
    }
}

该位置格式字符串中的* 表示采用指定该字段宽度的另一个参数。不过我错过了,我并不感到惊讶;格式字符串实际上是一种非常密集的微语言,很容易跳过一个重要的位。 (对于使用它们的所有其他语言也是如此;很少有人知道你可以用它们做的所有事情。)

您可以使用固定字段集执行更多智能操作,而其他% - 序列也支持*。请注意,我通常必须进行实验以获得我想要的内容(尤其是浮点数...)

答案 1 :(得分:4)

解决此问题的最简单方法是使用struct :: matrix包,tcllib的一部分:

package require struct::matrix

set lines {
    {Administrator 15-05-2011 16:05}
    {confuser 01-02-2011 20:57}
    {Public 29-01-2011 19:28}
    {TechM 30-04-2011 09:47}
    {"Name with space" 29-04-2011 11:05}
}

struct::matrix m; # Create a new matrix
m add columns 3; # The matrix has 3 columns: file name, date, and time
foreach line $lines {
    m add row $line; # Add a line to the matrix
}
m format 2chan; # Prints it out

输出:

Administrator   15-05-2011 16:05
confuser        01-02-2011 20:57
Public          29-01-2011 19:28
TechM           30-04-2011 09:47
Name with space 29-04-2011 11:05

注意:

  1. 如果字段包含空格,则应使用双引号引用该字段(请参阅带空格的名称)
  2. 格式2chan 命令仅格式化左对齐格式字段。如果您正在寻找中心或右对齐,请查看报告包。

答案 2 :(得分:2)

您必须首先收集要显示的所有记录,然后找到要放在第一个输出列中的最长字符串的大小;我们称之为max_len。然后,知道该大小,您将在第一列中输出要输出的每个字符串,并在右侧(在字符串的末尾)使用那么多空格字符,结果总长度恰好为max_len(提示:使用string repeat " " [expr {$max_len - [string length $s]}]构造填充块)然后使用该填充输出字符串。

顺便说一下,您可以看到parray标准命令是如何实现的,因为它完全符合您的要求。要查看其实现,请执行

set x {Administrator foo Molly bar Dolly blorb}
parray x
info body parray

在交互式Tcl shell提示符中(建议使用tkcon)。

相关问题