简体   繁体   English

awk-以3列格式打印输出

[英]awk - Printing output in 3 column format

I have a text file of data that appears in the following format. 我有一个数据文本文件,它以以下格式显示。

apropos c
awk nc
chsh c
date nc
grep nc
i3 nc
ip6tables nc

I am trying to filter this data through awk, to produce a 3 column format, similar to below. 我正在尝试通过awk过滤此数据,以产生3列格式,类似于以下内容。

apropos          awk          chsh
date             grep         i3

I do not need the second column of information on the file, but would like a clean and aligned output of the first column. 我不需要文件的第二列信息,但希望第一列的输出干净整齐。 I found the following code elsewhere, and modified it a bit to only output the first column of data. 我在其他地方找到了以下代码,并对其进行了一些修改以仅输出第一列数据。 Problem is that it comes out misaligned due to the usage of tabs. 问题是由于使用制表符而导致未对齐。

awk '{printf (NR %3 == 0 )? $1 "\n" : $1"\t\t" }'

Doing a bit more research I found the usage of width via awk's printf (ie. "%-10s"). 经过更多研究,我发现通过awk的printf(即“%-10s”)使用宽度。 Only problem is I am not quite sure how to integrate it into my command to get it to do what I'd like. 唯一的问题是我不太确定如何将其集成到命令中以使其执行所需的操作。 Any help would be appreciated, thanks! 任何帮助,将不胜感激,谢谢!

This might be more useful to you than hard-coding some arbitrary field width like 10 : 这比硬编码某些任意字段宽度(例如10对您更有用:

$ awk '{ORS=(NR%3?FS:RS); print $1}' file | column -t
apropos    awk   chsh
date       grep  i3
ip6tables

or if you do want to drop ip6tables from the output as shown in your sample input/output: 或者,如果您确实想从输出中删除ip6tables ,如示例输入/输出所示:

$ awk '{rec = rec OFS $1} !(NR%3){print rec; rec=""}' file | column -t
apropos  awk   chsh
date     grep  i3

If you don't pipe to column and don't want to pick some arbitrary number as the field width then you need awk to make 2 passes of the input file to figure out the max width of each column first before printing (see https://stackoverflow.com/a/38791539/1745001 ). 如果您不通过管道传递到column并且不想选择任意数字作为字段宽度,则需要awk对输入文件进行2次遍历,以便在打印之前首先确定每列的最大宽度(请参阅https: //stackoverflow.com/a/38791539/1745001 )。

wrt the first example - running any UNIX tool on input that does not end in a newline is relying on undefined behavior per the POSIX spec so if your column gives a warning when there's a missing newline after ip6tables then add it: 在第一个示例中-在未以换行符结尾的输入上运行任何UNIX工具都依赖于POSIX规范的未定义行为,因此如果您的columnip6tables后缺少换行符时发出警告,则添加它:

$ awk '{ORS=(NR%3?FS:RS); print $1} END{if (NR%3) printf "%s", RS}' file | column -t
apropos    awk   chsh
date       grep  i3
ip6tables

You can use the following awk | column 您可以使用以下awk | column awk | column pipe: awk | column管:

awk '{sep=NR%3?OFS:ORS;printf "%s%s", $1, sep}END{if(NR%3)print ""}' a.txt  \
  | column  -t

Note: Since (at least) the BSD version of the column command will print a warning: 注意:由于(至少)column命令的BSD版本将显示警告:

column: line too long

and omit the last line in case the number of lines in the list is not a multiple of the column count you need to print a newline after the last element in that case. 并省略最后一行,以防列表中的行数不是列数的倍数,在这种情况下,您需要在最后一个元素之后打印换行符。

a non-awk solution 非奥克解决方案

$ cut -d' ' -f1 <file | paste - - - | column -t

apropos    awk   chsh
date       grep  i3
ip6tables

or with pr 或与pr

$ cut -d' ' -f1 <file | pr -3at

apropos                 awk                     chsh
date                    grep                    i3
ip6tables

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM