11

我想知道如何格式化以下输出:

-0.3116274D-04
-0.2389361D-04
-0.1192458D-04
0.3306203D-04
0.2534987D-04
0.1265136D-04
-0.2167920D-04
-0.3713258D-04
-0.2294900D-05
-0.4151710D-05
-0.7674479D-03
-0.5749288D-04
0.1393479D-04
0.6763913D-04
0.2515100D-05
-0.3638000D-06
-0.2630000D-06
-0.2445230D-06
0.1534680D-05
0.1579750D-04
0.2922010D-04
0.5390530D-04
0.8701990D-04
0.1132741D-03
0.9665700D-04
0.3337340D-04
-0.4121240D-05

通过首先转置为五列:

-0.3116274D-04  -0.2389361D-04  -0.1192458D-04   0.3306203D-04   0.2534987D-04
 0.1265136D-04  -0.2167920D-04  -0.3713258D-04  -0.2294900D-05  -0.4151710D-05
-0.7674479D-03  -0.5749288D-04   0.1393479D-04   0.6763913D-04   0.2515100D-05
-0.3638000D-06  -0.2630000D-06  -0.2445230D-06   0.1534680D-05   0.1579750D-04
 0.2922010D-04   0.5390530D-04   0.8701990D-04   0.1132741D-03   0.9665700D-04
 0.3337340D-04  -0.4121240D-05          

我的第一种方法是:

sed 's/\n//g' File | column -n
4

5 回答 5

27

尝试这个:

printf "%14s  %14s  %14s  %14s  %14s\n" $(cat data.txt)
于 2013-11-08T02:30:33.340 回答
8

可能应该使用托盘粗体字答案,但请注意最后一行是空白填充到全宽。此外,如果数据文件非常大(可能是 256 KiB;几乎可以肯定在达到 1 MiB 之前),您将用完. 以下解决方案适用于大小为数兆字节的文件,而不会对系统产生不利影响。printf "%14s %14s %14s %14s %14s\n" $(cat data.txt)printf

您几乎可以pr在多列模式 ( pr -5 -l1 -t) 中使用,但它会使列左对齐,因此-无法正确显示符号。OTOH,然后您可以将输出输入 awk 以进行右对齐:

pr -5 -l1 -t File | awk '{ printf "%14s %14s %14s %14s %14s\n", $1, $2, $3, $4, $5 }'

但如果你要拖入awk游戏,它也可以为你做“换位”——不过,它只需要更多的编码来做到这一点。

您的建议几乎可行,但是当我尝试时,我得到0.8725220D- 0.1609633D- 0.2598447D-:每个数字的指数都消失了。

的一些奇迹pr。默认情况下,它使用制表符来分隔列。您可以使用-s' '或指定输出宽度更宽(例如-w100)来覆盖它。请注意,需要将诸如空格之类的参数值附加到选项,至少在传统实现中pr(但-w 100可以正常工作)。

$ pr -s' ' -5 -l1 -t data | awk '{printf "%14s  %14s  %14s  %14s  %14s\n", $1, $2, $3, $4, $5}'
-0.3116274D-04  -0.2389361D-04  -0.1192458D-04   0.3306203D-04   0.2534987D-04
 0.1265136D-04  -0.2167920D-04  -0.3713258D-04  -0.2294900D-05  -0.4151710D-05
-0.7674479D-03  -0.5749288D-04   0.1393479D-04   0.6763913D-04   0.2515100D-05
-0.3638000D-06  -0.2630000D-06  -0.2445230D-06   0.1534680D-05   0.1579750D-04
 0.2922010D-04   0.5390530D-04   0.8701990D-04   0.1132741D-03   0.9665700D-04
 0.3337340D-04  -0.4121240D-05                                                
$ pr -w 100 -5 -l1 -t data | awk '{printf "%14s  %14s  %14s  %14s  %14s\n", $1, $2, $3, $4, $5}'
-0.3116274D-04  -0.2389361D-04  -0.1192458D-04   0.3306203D-04   0.2534987D-04
 0.1265136D-04  -0.2167920D-04  -0.3713258D-04  -0.2294900D-05  -0.4151710D-05
-0.7674479D-03  -0.5749288D-04   0.1393479D-04   0.6763913D-04   0.2515100D-05
-0.3638000D-06  -0.2630000D-06  -0.2445230D-06   0.1534680D-05   0.1579750D-04
 0.2922010D-04   0.5390530D-04   0.8701990D-04   0.1132741D-03   0.9665700D-04
 0.3337340D-04  -0.4121240D-05  
$

所有这些pr | awk解决方案都将最后一行空白填充到全宽。

下面是两个awk在一个命令中完成工作的等效脚本。一个将代码分成 2 行,另一个超过 16 行(但更容易阅读):

选项1:

awk '{ a[i++] = $0; if (i == 5) { printf "%14s  %14s  %14s  %14s  %14s\n", a[0], a[1], a[2], a[3], a[4]; i = 0; } }
     END { if (i > 0) { printf "%14s", a[0]; for (j = 1; j < i; j++) printf "  %14s", a[j]; printf "\n"; } }' data

选项 2:

awk '{  a[i++] = $0
        if (i == 5)
        {
            printf "%14s  %14s  %14s  %14s  %14s\n", a[0], a[1], a[2], a[3], a[4]
            i = 0
        }
     }
     END {
        if (i > 0)
        {
            printf "%14s", a[0]
            for (j = 1; j < i; j++)
                printf "  %14s", a[j]
            printf "\n"
        }
     }' data

输出与以前相同,只是这些空白都没有填充最后一行:

-0.3116274D-04  -0.2389361D-04  -0.1192458D-04   0.3306203D-04   0.2534987D-04
 0.1265136D-04  -0.2167920D-04  -0.3713258D-04  -0.2294900D-05  -0.4151710D-05
-0.7674479D-03  -0.5749288D-04   0.1393479D-04   0.6763913D-04   0.2515100D-05
-0.3638000D-06  -0.2630000D-06  -0.2445230D-06   0.1534680D-05   0.1579750D-04
 0.2922010D-04   0.5390530D-04   0.8701990D-04   0.1132741D-03   0.9665700D-04
 0.3337340D-04  -0.4121240D-05

编写这样的代码会更容易、更短;重置代码也delete a可以清除数组,END 块将简单地测试i并使用printf主代码中的:

awk '{  a[i++] = $0
        if (i == 5)
        {
            printf "%14s  %14s  %14s  %14s  %14s\n", a[0], a[1], a[2], a[3], a[4]
            i = 0
            delete a
        }
     }
     END {
        if (i > 0) printf "%14s  %14s  %14s  %14s  %14s\n", a[0], a[1], a[2], a[3], a[4]
     }' data
于 2013-11-08T03:44:37.750 回答
1
$ awk '{ORS=(NR%5?FS:RS)}1' file
-0.3116274D-04 -0.2389361D-04 -0.1192458D-04 0.3306203D-04 0.2534987D-04
0.1265136D-04 -0.2167920D-04 -0.3713258D-04 -0.2294900D-05 -0.4151710D-05
-0.7674479D-03 -0.5749288D-04 0.1393479D-04 0.6763913D-04 0.2515100D-05
-0.3638000D-06 -0.2630000D-06 -0.2445230D-06 0.1534680D-05 0.1579750D-04
0.2922010D-04 0.5390530D-04 0.8701990D-04 0.1132741D-03 0.9665700D-04
0.3337340D-04 -0.4121240D-05 $

请注意,如果行数不是 5 的倍数,它不会在末尾添加换行符。这是一个问题吗?

于 2013-11-08T10:44:04.913 回答
0

哇,好久没看到这个了。有几种方法:

ol' pr命令用于这种类型的工作——特别是如果您希望这些列垂直而不是水平。

但是,我会使用printf它来使文​​本保持恒定宽度,然后在一行中有五个项目时使用计数器和模运算符进行计数。运算符有时称为余数运算符。但是,它的功能类似于时钟:

#!/bin/bash
# 

count=0
while read number
do
    ((count+=1))
    printf "%14.14s  " $number
    if ((count % 5 == 0))
    then
        printf "\n"
    fi
done < $file
printf "\n"

的格式printf缺少减号( ie %-14.14s),它强制文本向右而不是向左对齐。这样,减号不会让我失望。

于 2013-11-08T02:43:44.433 回答
0

一个有点棘手的选择:

columnPrint(){
select foo in $(cat); do break; done; <<!SELECTEOF
1
!SELECTEOF
};

cat data.txt | columnPrint;
# or simply columnPrint < data.txt

与@traybold 方法相比,它的缺点是项目被编号(这可能不是您想要的),但它还具有自动调整列数以适应输入字符串和终端宽度的优点。

于 2016-02-25T10:22:23.730 回答