我对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:47am接收的输出是根据第一个字符串中存在的字母数,例如管理员混淆公共技术。所以我需要知道的是如何得到一个不考虑第一个字符串长度的输出,并给出一个适当的均匀列输出。
发布于 2011-09-12 17:17:17
廉价的hack方法是使用制表符作为输出字符串中的分隔符(“\t”而不是“”)。这将适用于少量的变化,但不能处理较大的变化(或当前终端/编辑器选项卡宽度的小变化)。
要正确完成这项工作,首先需要获得要打印的所有概念性行的列表(即,数据但尚未格式化)。然后遍历每一行,计算出每个字段所需的宽度,取整个数据集的最大值。这样,您就可以为format配置格式字符串了。下面是一个示例(对于TCL8.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
}
}格式字符串中该位置的*表示接受指定该字段宽度的另一个参数。不过,我并不奇怪您错过了它;格式化字符串实际上是一种非常密集的微语言,很容易跳过一个重要的部分。(对于使用它们的所有其他语言也是如此;很少有人知道您可以用它们做什么。)
您可以使用固定的字段集做更智能的事情,其他%-sequences也支持*。请注意,我通常必须进行实验才能得到我想要的东西(特别是浮点数…)。
发布于 2011-09-12 23:23:18
解决这个问题最简单的方法是使用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备注:
发布于 2011-09-12 17:03:32
您必须首先收集要显示的所有记录,然后找到要放在第一个输出列中的最长字符串的大小;我们称其为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)。
https://stackoverflow.com/questions/7384349
复制相似问题