如何将包含单个列的文本文件转换为矩阵?

时间:2017-05-25 16:08:06

标签: linux bash unix text awk

我有一个包含一列数字的文本文件,如下所示:

1
2
3
4
5
6

我想将它转换为两列,按照从左到右的顺序:

1 2
3 4
5 6

我可以用:

awk '{print>"line-"NR%2}' file
paste line-0  line-1 >newfile

但我认为依赖两个中间文件会使脚本变得脆弱。

我想使用像cat file | mystery-zip-command >newfile

这样的东西

7 个答案:

答案 0 :(得分:3)

您可以使用paste执行此操作:

paste -d " " - - < file > newfile

您还可以使用pr

pr -ats" " -2 file > newfile
  • -a - 使用循环订单
  • -t - 禁止标题和预告片
  • -s " " - 使用单个空格作为分隔符
  • -2 - 两列输出

另见:

答案 1 :(得分:3)

另一种选择

$ seq 6 | xargs -n2

1 2
3 4
5 6

awk

$ seq 6 | awk '{ORS=NR%2?FS:RS}1'

1 2
3 4
5 6

如果你希望输出以奇数个输入行的情况终止一个新行。

$ seq 7 | awk '{ORS=NR%2?FS:RS}1; END{ORS=NR%2?RS:FS; print ""}'

1 2
3 4
5 6
7

答案 2 :(得分:2)

awk 'NR % 2 == 1 { printf("%s", $1) }
     NR % 2 == 0 { printf(" %s\n", $1) }
     END { if (NR % 2 == 1) print "" }' file

打印奇数行后面没有换行符,打印第一列。偶数行首先打印空格,然后打印换行符,以打印第二列。最后,如果有奇数行,我们会打印换行符,这样我们就不会在行中间结束。

答案 3 :(得分:1)

awk 方法:

awk '{print ( ((getline nl) > 0)? $0" "nl : $0 )}' file

输出:

1 2
3 4
5 6
  • (getline nl)>0 - getline将获取下一条记录并将其分配给变量nl getline 命令如果找到记录则返回1,如果遇到文件末尾则返回0

GNU sed 方法:

sed 'N;s/\n/ /' file
  • N - 在图案空间中添加换行符,然后将下一行输入附加到图案空间

  • s/\n/ / - 在捕获的模式空间中用空格替换换行符

答案 4 :(得分:1)

使用bash:

while IFS= read -r odd; do IFS= read -r even; echo "$odd $even"; done < file

输出:

1 2
3 4
5 6

答案 5 :(得分:1)

$ seq 6 | awk '{ORS=(NR%2?FS:RS); print} END{if (ORS==FS) printf RS}'
1 2
3 4
5 6
$
$ seq 7 | awk '{ORS=(NR%2?FS:RS); print} END{if (ORS==FS) printf RS}'
1 2
3 4
5 6
7
$

请注意,它总是添加一个终止换行符 - 这很重要,因为将来的命令可能依赖于它,例如:

$ seq 6 | awk '{ORS=(NR%2?FS:RS); print}' | wc -l
       3
$ seq 7 | awk '{ORS=(NR%2?FS:RS); print}' | wc -l
       3
$ seq 7 | awk '{ORS=(NR%2?FS:RS); print} END{if (ORS==FS) printf RS}' | wc -l
       4

如果您的要求发生变化,只需将2的单个匹配项更改为3或您想要的列数如下:

$ seq 6 | awk '{ORS=(NR%3?FS:RS); print} END{if (ORS==FS) printf RS}'
1 2 3
4 5 6
$ seq 7 | awk '{ORS=(NR%3?FS:RS); print} END{if (ORS==FS) printf RS}'
1 2 3
4 5 6
7
$ seq 8 | awk '{ORS=(NR%3?FS:RS); print} END{if (ORS==FS) printf RS}'
1 2 3
4 5 6
7 8
$ seq 9 | awk '{ORS=(NR%3?FS:RS); print} END{if (ORS==FS) printf RS}'
1 2 3
4 5 6
7 8 9
$

答案 6 :(得分:0)

seq 6 | tr '\n' ' ' | sed -r 's/([^ ]* [^ ]* )/\1\n/g'