如果我的第二列发生变化,如何保持第三列不变

如果我的第二列发生变化,如何保持第三列不变

我有一个命令的输出。

CPU_SrcID#0_MC#0_Chan#0_DIMM#0  0  0      A1
CPU_SrcID#0_MC#0_Chan#1_DIMM#0  0  0      A2
CPU_SrcID#0_MC#0_Chan#2_DIMM#0  0  0      A3
CPU_SrcID#0_MC#1_Chan#0_DIMM#0  0  0      A4
CPU_SrcID#0_MC#1_Chan#1_DIMM#0  0  0      A5
CPU_SrcID#0_MC#1_Chan#2_DIMM#0  0  1      A6
CPU_SrcID#1_MC#0_Chan#0_DIMM#0  0  0      B1
CPU_SrcID#1_MC#0_Chan#1_DIMM#0  0  0      B2
CPU_SrcID#1_MC#0_Chan#2_DIMM#0  0  0      B3
CPU_SrcID#1_MC#1_Chan#0_DIMM#0  0  0      B4
CPU_SrcID#1_MC#1_Chan#1_DIMM#0  0  0      B5
CPU_SrcID#1_MC#1_Chan#2_DIMM#0  0  0      B6

所以我所有的专栏都是直的。唯一改变的数字是第 2 列和第 3 列中的数字。但是,如果其中一个数字更改为小数点后两位或更多,我的第三列将与其余列不一致。

CPU_SrcID#0_MC#0_Chan#0_DIMM#0  0  0      A1
CPU_SrcID#0_MC#0_Chan#1_DIMM#0  15  0      A2
CPU_SrcID#0_MC#0_Chan#2_DIMM#0  0  0      A3
CPU_SrcID#0_MC#1_Chan#0_DIMM#0  0  0      A4
CPU_SrcID#0_MC#1_Chan#1_DIMM#0  0  0      A5
CPU_SrcID#0_MC#1_Chan#2_DIMM#0  0  347      A6
CPU_SrcID#1_MC#0_Chan#0_DIMM#0  0  0      B1
CPU_SrcID#1_MC#0_Chan#1_DIMM#0  0  0      B2
CPU_SrcID#1_MC#0_Chan#2_DIMM#0  0  0      B3
CPU_SrcID#1_MC#1_Chan#0_DIMM#0  0  0      B4
CPU_SrcID#1_MC#1_Chan#1_DIMM#0  0  0      B5
CPU_SrcID#1_MC#1_Chan#2_DIMM#0  0  0      B6

无论数字有多少位小数,如何才能保持列的正确性?这就是我希望的样子。

CPU_SrcID#0_MC#0_Chan#0_DIMM#0  0  0      A1
CPU_SrcID#0_MC#0_Chan#1_DIMM#0  15 0      A2
CPU_SrcID#0_MC#0_Chan#2_DIMM#0  0  0      A3
CPU_SrcID#0_MC#1_Chan#0_DIMM#0  0  0      A4
CPU_SrcID#0_MC#1_Chan#1_DIMM#0  0  0      A5
CPU_SrcID#0_MC#1_Chan#2_DIMM#0  0  347    A6
CPU_SrcID#1_MC#0_Chan#0_DIMM#0  0  0      B1
CPU_SrcID#1_MC#0_Chan#1_DIMM#0  0  0      B2
CPU_SrcID#1_MC#0_Chan#2_DIMM#0  0  0      B3
CPU_SrcID#1_MC#1_Chan#0_DIMM#0  0  0      B4
CPU_SrcID#1_MC#1_Chan#1_DIMM#0  0  0      B5
CPU_SrcID#1_MC#1_Chan#2_DIMM#0  0  0      B6

答案1

如果您无法修改代码产生格式化从一开始就生成对齐列的数据,然后您可以使用该column实用程序对输出进行后处理:

some_command | column -t

运行问题中未对齐的数据column -t会产生以下输出:

CPU_SrcID#0_MC#0_Chan#0_DIMM#0  0   0    A1
CPU_SrcID#0_MC#0_Chan#1_DIMM#0  15  0    A2
CPU_SrcID#0_MC#0_Chan#2_DIMM#0  0   0    A3
CPU_SrcID#0_MC#1_Chan#0_DIMM#0  0   0    A4
CPU_SrcID#0_MC#1_Chan#1_DIMM#0  0   0    A5
CPU_SrcID#0_MC#1_Chan#2_DIMM#0  0   347  A6
CPU_SrcID#1_MC#0_Chan#0_DIMM#0  0   0    B1
CPU_SrcID#1_MC#0_Chan#1_DIMM#0  0   0    B2
CPU_SrcID#1_MC#0_Chan#2_DIMM#0  0   0    B3
CPU_SrcID#1_MC#1_Chan#0_DIMM#0  0   0    B4
CPU_SrcID#1_MC#1_Chan#1_DIMM#0  0   0    B5
CPU_SrcID#1_MC#1_Chan#2_DIMM#0  0   0    B6

这样做的一个可能的缺点是column -t将列之间的最小距离缩小到两个空间。

您还可以通过与数据一起输出对齐字符(字段分隔符)来“修复”此问题,如下面未对齐的数据所示:

CPU_SrcID#0_MC#0_Chan#0_DIMM#0  |0  |0      |A1         
CPU_SrcID#0_MC#0_Chan#1_DIMM#0  |15  |0      |A2        
CPU_SrcID#0_MC#0_Chan#2_DIMM#0  |0  |0      |A3         
CPU_SrcID#0_MC#1_Chan#0_DIMM#0  |0  |0      |A4         
CPU_SrcID#0_MC#1_Chan#1_DIMM#0  |0  |0      |A5         
CPU_SrcID#0_MC#1_Chan#2_DIMM#0  |0  |347      |A6       
CPU_SrcID#1_MC#0_Chan#0_DIMM#0  |0  |0      |B1         
CPU_SrcID#1_MC#0_Chan#1_DIMM#0  |0  |0      |B2         
CPU_SrcID#1_MC#0_Chan#2_DIMM#0  |0  |0      |B3         
CPU_SrcID#1_MC#1_Chan#0_DIMM#0  |0  |0      |B4         
CPU_SrcID#1_MC#1_Chan#1_DIMM#0  |0  |0      |B5         
CPU_SrcID#1_MC#1_Chan#2_DIMM#0  |0  |0      |B6        

使用column -t -s '|'此数据将导致

CPU_SrcID#0_MC#0_Chan#0_DIMM#0    0     0          A1         
CPU_SrcID#0_MC#0_Chan#1_DIMM#0    15    0          A2        
CPU_SrcID#0_MC#0_Chan#2_DIMM#0    0     0          A3         
CPU_SrcID#0_MC#1_Chan#0_DIMM#0    0     0          A4         
CPU_SrcID#0_MC#1_Chan#1_DIMM#0    0     0          A5         
CPU_SrcID#0_MC#1_Chan#2_DIMM#0    0     347        A6       
CPU_SrcID#1_MC#0_Chan#0_DIMM#0    0     0          B1         
CPU_SrcID#1_MC#0_Chan#1_DIMM#0    0     0          B2         
CPU_SrcID#1_MC#0_Chan#2_DIMM#0    0     0          B3         
CPU_SrcID#1_MC#1_Chan#0_DIMM#0    0     0          B4         
CPU_SrcID#1_MC#1_Chan#1_DIMM#0    0     0          B5         
CPU_SrcID#1_MC#1_Chan#2_DIMM#0    0     0          B6

答案2

一般来说,这取决于您生成数据的方式。例如,如果您有printf某种类型的语句(无论是 C、bash 还是其他语言),您需要设置字段宽度。

例如在bash中:

printf "%30s %3d %3d %5s" "CPU_SrcID#1_MC#1_Chan#2_DIMM#0" 0 347 A6

只要数字最多有 3 位数字,就会将其排列起来。

如果您无法控制生成,则排列字段的通用方法是命令column。将你的命令通过管道输入column -t,然后将它们排列起来,如下所示:

CPU_SrcID#0_MC#0_Chan#0_DIMM#0  0   0    A1
CPU_SrcID#0_MC#0_Chan#1_DIMM#0  15  0    A2
CPU_SrcID#0_MC#0_Chan#2_DIMM#0  0   0    A3
CPU_SrcID#0_MC#1_Chan#0_DIMM#0  0   0    A4
CPU_SrcID#0_MC#1_Chan#1_DIMM#0  0   0    A5
CPU_SrcID#0_MC#1_Chan#2_DIMM#0  0   347  A6
CPU_SrcID#1_MC#0_Chan#0_DIMM#0  0   0    B1
CPU_SrcID#1_MC#0_Chan#1_DIMM#0  0   0    B2
CPU_SrcID#1_MC#0_Chan#2_DIMM#0  0   0    B3
CPU_SrcID#1_MC#1_Chan#0_DIMM#0  0   0    B4
CPU_SrcID#1_MC#1_Chan#1_DIMM#0  0   0    B5
CPU_SrcID#1_MC#1_Chan#2_DIMM#0  0   0    B6

请注意,这会将数字左对齐,而不是像右对齐printf。通常右对齐数字更好,因此最好更改代。在某些版本上,column您可以添加一个选项-R 2,3来右对齐这两列,但您的版本可能没有该选项。

如果您想对格式进行更多控制,可以将输出通过管道传输到循环中while read,并用于printf重新打印值,如下所示:

command | while read label num1 num2 code
do printf "%30s %3d %3d      %2s\n" "$label" "$num1" "$num2" "$code"
done

相关内容