bash 按列格式化输出

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19850403/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 00:24:26  来源:igfitidea点击:

Format output in columns

bashsedawkgrep

提问by Another.Chemist

I was wondering how to format the following output:

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

-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

into five columns, by transposing first:

分为五列,首先转置:

-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          

My first approach was:

我的第一种方法是:

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

回答by traybold

Try this:

尝试这个:

printf "%14s  %14s  %14s  %14s  %14s\n" $(cat data.txt)

回答by Jonathan Leffler

The answerby trayboldusing printf "%14s %14s %14s %14s %14s\n" $(cat data.txt)and should probably be used, but be aware that the last line is blank padded to full width. Also, if the data file is very big (256 KiB perhaps; almost certainly before you reach 1 MiB), you will run out of space for the command line arguments to printf. The solutions below will work with files that are many megabytes in size without adversely affecting the system.

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

You can almost use prin multi-column mode (pr -5 -l1 -t), but it left-justifies the columns, so the -signs won't be presented correctly. OTOH, you could then feed the output into awk to do the right-justification:

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

pr -5 -l1 -t File | awk '{ printf "%14s %14s %14s %14s %14s\n", , , , ,  }'

but if you're going to drag awkinto the game, it can also do the 'transposition' for you — it just takes a bit more coding to do that, though.

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

Your suggestion almost works, but when I tried it, I get: 0.8725220D- 0.1609633D- 0.2598447D-; the exponent of each number is gone.

您的建议差不多的作品,但是当我尝试了,我得到:0.8725220D- 0.1609633D- 0.2598447D-; 每个数字的指数都消失了。

Some of the wonders of pr. By default, it uses tabs to separate columns. You can override that with -s' 'or by specifying that the output width is wider (e.g. -w100). Note that argument values such as the space need to be attached to the option, at least in traditional implementations of pr(but -w 100works OK).

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

$ pr -s' ' -5 -l1 -t data | awk '{printf "%14s  %14s  %14s  %14s  %14s\n", , , , , }'
-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", , , , , }'
-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  
$

All these pr | awksolutions blank-pad the last line to full width.

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

Here are two equivalent awkscripts that do the job in one command. One spreads the code over 2 lines, the other over 16 lines (but it is easier to read):

下面是两个等效的awk脚本,它们在一个命令中完成这项工作。一个将代码扩展到 2 行,另一个扩展到 16 行(但更容易阅读):

Option 1:

选项1:

awk '{ a[i++] = 
awk '{  a[i++] = 
-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
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
; 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

Option 2:

选项 2:

awk '{  a[i++] = 
$ 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 $
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

The output is the same as before except that neither of these blank-pads the last line:

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

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

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

It would be easier and shorter to write code that did; the reset code would also do delete ato clear the array and the END block would simply test iand use the printffrom the main code:

编写这样的代码会更容易、更短;重置代码也delete a可以清除数组,END 块将简单地测试i和使用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"

回答by Ed Morton

##代码##

Note that it doesn't put a newline at the end if the number of lines aren't a multiple of 5. Is that a concern?

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

回答by bitifet

A little bit tricky alternative:

一个有点棘手的选择:

##代码##

Compared with @traybold approach, it has the drawback that items are numbered (which could not be what you want), but it also has the advantage of automatically adapting the number of columns to the input strings and terminal width.

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

回答by David W.

Wow, haven't seen this in a while. There are several ways:

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

The ol' prcommand was used for this type of work -- especially if you wanted those columns going vertically instead of horizontally.

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

However, I would use printfwhich allows me to keep the text a constant width, and then use a counter and the modulooperator to count when I have five items in a line. The modulooperator is sometimes called a remainderoperator. However, it functions like a clock:

但是,我会使用printfwhich 允许我保持文本的恒定宽度,然后在一行中有五个项目时使用计数器和运算符进行计数。该操作有时被称为运算符。然而,它的功能就像一个时钟:

##代码##

The format for the printfis missing the minus ( i.e. %-14.14s) which forces the text to be aligned to the right instead of the left. That way the minus doesn't throw me off.

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