首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在tcl中统一显示输出

如何在tcl中统一显示输出
EN

Stack Overflow用户
提问于 2011-09-12 15:03:16
回答 3查看 10K关注 0票数 4

我对format命令有疑问。我的输出是一种集群和不均匀,如下所示

代码语言:javascript
复制
    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],它给我的输出如下:

代码语言:javascript
复制
Administrator 15-05-2011 16:05 
confuser 01-02-2011 20:57 
Public 29-01-2011 19:28 
TechM 30-04-2011 09:47

am接收的输出是根据第一个字符串中存在的字母数,例如管理员混淆公共技术。所以我需要知道的是如何得到一个不考虑第一个字符串长度的输出,并给出一个适当的均匀列输出。

EN

回答 3

Stack Overflow用户

发布于 2011-09-12 17:17:17

廉价的hack方法是使用制表符作为输出字符串中的分隔符(“\t”而不是“”)。这将适用于少量的变化,但不能处理较大的变化(或当前终端/编辑器选项卡宽度的小变化)。

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

代码语言:javascript
复制
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
    }
}

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

您可以使用固定的字段集做更智能的事情,其他%-sequences也支持*。请注意,我通常必须进行实验才能得到我想要的东西(特别是浮点数…)。

票数 7
EN

Stack Overflow用户

发布于 2011-09-12 23:23:18

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

代码语言:javascript
复制
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

输出:

代码语言:javascript
复制
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. format 2chan命令
  3. format字段左对齐。如果您正在查看居中或右对齐,请查找报表包。
票数 4
EN

Stack Overflow用户

发布于 2011-09-12 17:03:32

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

顺便说一句,您可以看到parray标准命令是如何实现的,因为它所做的正是您想要的。要查看其实现,请执行

代码语言:javascript
复制
set x {Administrator foo Molly bar Dolly blorb}
parray x
info body parray

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

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7384349

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档