英文:
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 '\t\n' file | column -t
One Two
Three Four
Five Six
(Alternatively, paste -sd '\t\n' - <file | column -t
)
The key is that paste
alternates between the two characters in the -d 'xy'
string:
$ seq 10 | paste -sd '!|' -
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 '\t\n' file
One Two
Three Four
Five Six
If you want three columns, you would do:
$ paste -sd '\t\t\n' file
One Two Three
Four Five Six
An alternative to paste
is this awk
:
$ awk '{ getline line; printf "%s\t%s\n", $0, line }' 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'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 '%s\t%s\n' $(<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. '%-20s %s\n'
, 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 'N; s/\n/ /g' 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 '%s\n' 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 - - < file | column -t
paste - - < 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 - - - < file | column -t
or with awk like this
awk '{ printf "%-8s", $1 } NR % 2 == 0 { printf "\n" }' 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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论