使用Linux的’column’实用工具。

huangapple go评论64阅读模式
英文:

Usage of linux 'column' utility

问题

我正在尝试从一个包含任意文本且没有任何空白的换行分隔数据文件中生成一个N列的表格。

例如,我有一个文件:

One
Two
Three
Four
Five
Six

我想在终端中显示这些数据如下:

One        Two
Three      Four
Five       Six

除非我误解了列的工作原理,它似乎不允许指定输出表格结构的任何方式。

没有任何参数时,cat file | column 简单地像 cat 一样将它们都显示在自己的行上。

使用 -t 或 --table 选项,它将它们都显示在同一行上 cat file | column -t

我尝试过所有参数的各种组合,以及 -t -C left -C right,试图将输出格式化为2列。

我还曾经很接近我想要的结果,使用 pr 工具:cat file | pr -t --columns 2

但是,由于一些单元格中有空白,它的格式不太正确,而且 pr 并没有提供其他的调整选项。

是否有人可以提供一个原生的Shell/Linux解决方案,以将文本序列列表显示为由N列组成的表格格式?

英文:

I'm trying to generate an N columned table from a file of newline delimited data containing arbitrary text without any whitespace.

For example, I have a file of:

One
Two
Three
Four
Five
Six

I would like to display this data in the terminal like so:

One        Two
Three      Four
Five       Six

Unless I'm misunderstanding how column works, it doesn't seem to allow for anyway to specify the output table structure.

Without any arguments cat file | column simply shows them all on their own line just like cat does.

With the -t --table option, it shows them all on the same line cat file | column -t

I have tried every combination of arguments along with -t -C left -C right to try and get the output formatted into 2 columns.

I have also come very close to what I want with the pr tool: cat file | pr -t --columns 2

However, the formatting isn't quite right because some of the cells have whitespace that shifts the alignment off and pr doesn't really offer any other adjustments.

Can anyone offer a native shell/linux solution to take a list of text sequence and display them in a tabular format consisting of N columns?

答案1

得分: 4

给定:

$ cat file
One
Two
Three
Four
Five
Six

你可以这样做:

$ paste -sd '\t\n' file | column -t
One    Two
Three  Four
Five   Six

(或者,paste -sd '\t\n' - <file | column -t

关键是在 -d 'xy' 字符串中,paste 在这两个字符之间交替:

$ seq 10 | paste -sd '!|' -
1!2|3!4|5!6|7!8|9!10

因此,要使用 paste 获得两列,可以将列分隔符与行分隔符交替使用:

$ paste -sd '\t\n' file
One    Two
Three  Four
Five   Six

如果你想要三列,可以这样做:

$ paste -sd '\t\t\n' file
One    Two    Three
Four   Five   Six

paste 的替代方法是使用这个 awk

$ awk '{ getline line; printf "%s\t%s\n", $0, line }' file
# 同样的输出

使用 awk 的好处是列和行结束之间的格式可以包含多个字符。

然后,为了使这两列对齐,可以在 awk 或 paste 之后的管道中使用 column -t

英文:

Given:

$ cat file
One
Two
Three
Four
Five
Six

You can do:

$ paste -sd &#39;\t\n&#39; file | column -t
One    Two
Three  Four
Five   Six

(Alternatively, paste -sd &#39;\t\n&#39; - &lt;file | column -t)

The key is that paste alternates between the two characters in the -d &#39;xy&#39; string:

$ seq 10 | paste -sd &#39;!|&#39; -
1!2|3!4|5!6|7!8|9!10

So to get two columns with paste, alternate the column separator with the line separator:

$ paste -sd &#39;\t\n&#39; file
One	Two
Three	Four
Five	Six

If you want three columns, you would do:

$ paste -sd &#39;\t\t\n&#39; file
One	Two	Three
Four	Five	Six

An alternative to paste is this awk:

$ awk &#39;{ getline line; printf &quot;%s\t%s\n&quot;, $0, line }&#39; file
# same output

The advantage to awk is the formatting between columns and line endings can be multiple characters.

Then to pad those two columns so they are straight, use column -t in a pipe after the awk or paste.

答案2

得分: 3

由于您使用的是bash,您可能无需使用外部实用程序就能完成这个任务:

```bash
$ cat i
One
Two
Three
Four
Five
Six

$ printf '%s\t%s\n' $(<i)
One     Two
Three   Four
Five    Six

这个方法有效是因为当printf用完格式变量时,它会重新使用其格式以处理额外的数据。对于非常大的数据集,您可能会遇到限制。

当然,如果您不喜欢制表符,您可以自由使用任何格式字符串,例如'%-20s %s\n'


<details>
<summary>英文:</summary>

Since you&#39;re in bash, you may be able to do this without external utilities at all:

```bash
$ cat i
One
Two
Three
Four
Five
Six

$ printf &#39;%s\t%s\n&#39; $(&lt;i)
One     Two
Three   Four
Five    Six

This works because when printf runs out of format variables, it just recycles its format to handle additional data. You may run up against limits for very large datasets.

Of course, if you don't like tabstops, you're free to use any format string you want. &#39;%-20s %s\n&#39;, for example.

答案3

得分: 3

column命令最初设计用于适应您的终端大小。默认情况下,它首先填充列,填充数量为您终端屏幕上显示的行数减一,然后再移动到下一列。这类似于报纸中文本的排列方式。在您的示例中,较少的项目无法填充第一列,这就是您无法看到效果的原因。

GNU column也可以通过使用-x选项来首先填充行,您肯定会在这里注意到差异。但除非您的屏幕非常窄,否则您还会注意到结果实际上不是您要寻找的内容:column将根据您终端的字符宽度和各种项目的宽度(与先前的模式一样)自行决定列数。

要在column中执行此操作的最佳方法是使用其表格模式,通过-t选项激活。在这里,您需要理解column只会期望输入已经格式化为表格 - 每行一行,列之间由空格(默认情况下)分隔。column有大量选项可用于调整结果,但基本上,它只会整理输出,使其显示为整洁的列。

要为您的目的使用column的表格模式,首先需要连接输入的相邻行。例如:

sed 'N; s/\n/ /g' file | column -t

当然,如果您的数据包含空格,则需要选择不同的字段分隔符。

请注意,即使在表格模式下,column的目标也是适应固定宽度的屏幕。您可以通过命令行选项控制它使用的宽度,如果您的项目很长或需要更多列,那么您可能需要这样做。

英文:

The column command was originally designed to fit the data to your terminal size. By default, it fills columns first, up to one less than the number of lines shown on your terminal screen, before moving to the next column. That's similar to the way text flows in a newspaper, for example. The few items in your example are not enough to fill the first column, which is why you don't discern the effect.

GNU column can also do the opposite by filling rows first, which you can request this with the -x option. You will definitely notice the difference here. But unless your screen is very narrow, you will also notice that the result is not really what you're looking for: column will decide the number of columns for itself (as it also did in the previous mode) based on the width of your terminal in characters and the widths of the various items.

Your best bet for doing this with column is to use its table mode, activated via option -t. Here you have to understand that column is just going to expect the input to already be formatted as a table -- one row per line, with columns separated by whitespace (by default). column has a large number of options for tweaking the result, but basically, it is just going to tidy that up so that it displays as neat columns.

To use column's table mode for your purpose, then, you first need to join adjacent rows of your input. For example:

sed &#39;N; s/\n/ /g&#39; file | column -t

Of course, if your data contain whitespace then you'll need to choose a different field separator.

Beware that even in table mode, column is aimed at fitting the output to a fixed-width screen. You can control the width it uses via command-line option, and you'll likely need to do that if some of your items are lengthy or if you want more than a very few columns.

答案4

得分: 2

这正是rs,即重塑命令,擅长的地方。在这里,我们只是通过rs 0 2(两列的未指定行)进行过滤:

#!/usr/bin/sh

printf '%s\n' One Two Three Four Five Six |
    rs 0 2
One    Two
Three  Four
Five   Six

与简单地使用制表符格式化不同,当条目长度不同时,它会执行正确的操作:

One           Two
Three         Four
Five          Six
Thirty-Three  Thirty-Four
英文:

This is exactly what rs, the reshape command, excels at. Here, we just filter through rs 0 2 (unspecified rows of two columns):

#!/usr/bin/sh

printf &#39;%s\n&#39; One Two Three Four Five Six |
    rs 0 2
One    Two
Three  Four
Five   Six

It does the right thing when the entries vary in length, unlike simply formatting with tabs:

One           Two
Three         Four
Five          Six
Thirty-Three  Thirty-Four

答案5

得分: 0

paste - - < file | column -t

  • paste - - < file 将文件的每两行合并为一行,以制表符分隔!

output

One Two
Three Four
Five Six

如果您想指定不同数量的列,可以相应地修改 paste,例如,要显示三列数据,可以使用:

paste - - - < file | column -t

或者使用 awk 如下:

awk '{ printf "%-8s", $1 } NR % 2 == 0 { printf "\n" }' file

正如您所见,您可以编辑 NR % 2 == 0 部分的条件,例如,要显示三列数据,您可以使用 NR % 3 == 0

output

One Two
Three Four
Five Six

英文:

also check this out :

paste - - &lt; file | column -t
  • paste - - &lt; file merges every two lines of the file into a single line, separated by a tab!

output

One    Two
Three  Four
Five   Six

and if you want to specify a different number of columns,you can modify the paste accordingly,for example, to display the data in three columns, you can use:

paste - - - &lt; file | column -t

or with awk like this

awk &#39;{ printf &quot;%-8s&quot;, $1 } NR % 2 == 0 { printf &quot;\n&quot; }&#39; file 

and as you see you can edit the condition in the NR % 2 == 0 part accordingly,for example, to display the data in three columns, you can use NR % 3 == 0!

output

One    Two
Three  Four
Five   Six

huangapple
  • 本文由 发表于 2023年8月4日 08:59:22
  • 转载请务必保留本文链接:https://go.coder-hub.com/76832364.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定