如何在 bash 中编写包含按第一个数字对齐的正数和负数的列

Boo*_*man 0 sorting bash awk sed sh

在处理包含正数和负数列的数据文件时,我想出了使用column -t. 但是,这会将 -ve 符号视为字段来对齐列,这看起来不太好。有没有什么方法(即使在内部column)以不同的方式对待它?

编辑: 实际情况不需要具有相同数量的数字,并且许多数字包含许多列。一个玩具示例如下:

猫输入.txt

-1.5647453E-09 1.33356715E-09
1.3224229E-09 4.8350685E-09
1.7098133E-09 -2.8287697E-10
-3.3301262E-09 -1.8597501E-08
Run Code Online (Sandbox Code Playgroud)

column -t

-1.5647453E-09  1.33356715E-09
1.3224229E-09   4.8350685E-09
1.7098133E-09   -2.8287697E-10
-3.3301262E-09  -1.8597501E-08
Run Code Online (Sandbox Code Playgroud)

预期的:

-1.5647453E-09   1.33356715E-09
 1.3224229E-09   4.8350685E-09
 1.7098133E-09  -2.8287697E-10
-3.3301262E-09  -1.8597501E-08 
Run Code Online (Sandbox Code Playgroud)

基本上,我想将每列从左侧(与第一个数字)对齐,以便它看起来如上。请注意,column -t它从左侧对齐,但也带有 -ve 符号,这是不需要的。

mar*_*rkp 5

假设:

  • -所有值的最大宽度(包括)均相同,均为 14 个字符
  • 所有行都有 2 列

一个简单的右对齐printf格式就足够了,例如,使用awk/printf

$ awk '{printf "%14s  %14s\n",$1,$2}' file
-1.5647453E-09   1.3335671E-09
 1.3224229E-09   4.8350685E-09
 1.7098133E-09  -2.8287697E-10
-3.3301262E-09  -1.8597501E-08
Run Code Online (Sandbox Code Playgroud)

假设:

  • -所有值的最大宽度(包括)均相同,均为 14 个字符
  • 行的列数可变

样本数据:

$ cat file
-1.5647453E-09 1.3335671E-09  4.8350685E-09
1.3224229E-09 4.8350685E-09  -4.8350685E-09  4.8350685E-09
1.7098133E-09 -2.8287697E-10    -2.8287697E-10
-3.3301262E-09 -1.8597501E-08  1.7098133E-09
Run Code Online (Sandbox Code Playgroud)

扩展前面的awk示例以处理可变数量的列:

awk '{for (i=1; i<=NF; i++) printf "%s%14s", (i==1 ? "" : "  "), $i; print ""}' file
Run Code Online (Sandbox Code Playgroud)

这会生成:

-1.5647453E-09   1.3335671E-09   4.8350685E-09
 1.3224229E-09   4.8350685E-09  -4.8350685E-09   4.8350685E-09
 1.7098133E-09  -2.8287697E-10  -2.8287697E-10
-3.3301262E-09  -1.8597501E-08   1.7098133E-09
Run Code Online (Sandbox Code Playgroud)

如果字段的宽度可以变化和/或列需要以不同的方式对齐(例如,小数对齐),则可以根据awk需要扩展代码......但此时我建议提出一个新问题,确保提供详细信息和更具代表性的样本数据集。