在Linux中合​​并文本文件的两列

Zoo*_*oma 6 linux bash

我有一个包含多列文本和值的文本文件.这个结构:

CAR       38
     DOG  42
CAT       89
CAR       23
     APE  18
Run Code Online (Sandbox Code Playgroud)

如果第1列有String,则第2列不具有(或者它实际上是一个emptry String).反过来说:如果第1列为空,则第2列有一个字符串.换句话说,"对象"(CAR,CAT,DOG等)出现在第1列或第2列中,但从不同时出现.

我正在寻找一种有效的方法来整合第1列和第2列,以便文件看起来像这样:

CAR  38
DOG  42
CAT  89
CAR  23
APE  18
Run Code Online (Sandbox Code Playgroud)

我可以使用while和if在Bash脚本中执行此操作,但我确信有一种更简单的方法.有人可以帮忙吗?

干杯! ž

Cyr*_*rus 17

试试这个:

column -t file
Run Code Online (Sandbox Code Playgroud)

输出:

CAR  38
DOG  42
CAT  89
CAR  23
APE  18


mkl*_*nt0 8

注意:如果:

  • 您正在寻找具有自动调整大小的左对齐固定宽度列的输出(最长的字段值确定宽度,较短的值用空格右边填充)
  • 并且很高兴有两个空格作为列分隔符
  • 并使用足够小的文件作为整体读入内存,

使用Cyrus更简单column的答案.

请参阅下文,了解column基于awk性能和资源消耗的基于方法的方法与下面的方法的比较.


awk 你的朋友在这里:

awk -v OFS='  ' '{ print $1, $2 }' file
Run Code Online (Sandbox Code Playgroud)
  • awk默认情况下由空格分割线成场,因此,与自己的输入,系如CAR 38DOG 42被解析相同的(CARDOG成为字段1,$13842成为场2, $2).
  • -v OFS=' '将输出字段分隔符设置为两个空格(默认为单个空格); 请注意,输出值不会填充以创建对齐的输出.

要使用不同宽度的字段创建对齐输出,请使用Awk的printf功能,这样可以更好地控制输出; 例如,下面输出一个10字符宽的左对齐第一列,以及一个2字符宽的右对齐第二列:

awk '{ printf "%-10s  %2s\n", $1, $2 }' file
Run Code Online (Sandbox Code Playgroud)
  • 请注意,列宽必须事先知道.
  • 相比之下,column -t通过首先解析所有数据,可以方便地自动确定列宽,但这会影响性能和资源消耗; 见下文.

column -t和Awk方法之间的性能/资源消耗比较:

  • column -t需要在第一遍中预先分析所有输入数据,以便能够确定最大输入列宽; 从我所知道的,它是通过首先将输入作为一个整体读入内存来实现的,这对于大输入文件可能是有问题的.
  • 相比之下,Awk解决方案逐个读取行 - 但依赖于提前知道列宽.

从而,

  • column -t消耗与输入大小成比例的内存,而awk将使用恒定的内存量.
  • column -t典型地更慢,这取决于使用的awk中执行; mawk更快,gawk更快,BSD awk更慢(!); 基于1000万行输入文件的结果; 命令在OSX 10.10.2和Ubuntu 14.04上运行.