每次看到模式时,将一列分成几列

时间:2016-08-29 22:07:14

标签: bash awk

我有一个非常简单的问题,但我发现很难解决这个问题。 我有两个很长的数据列,我想将它分成几列。每次在第一列中找到特定字符串时,脚本应该开始将数据写入新列: 输入:

A B
1 C 
2 C
3 C
4 C
A D
1 D
2 D
3 D
4 D

输出:

A B    A D
1 C    1 D
2 C    2 D
3 C    3 D
4 C    4 D

(分离模式为A)

5 个答案:

答案 0 :(得分:1)

使用粘贴功能:

$ awk '$1 == "A" { ++n } { print > ("t.tmp." n) }' input.txt
$ ls t.tmp.*
t.tmp.1 t.tmp.2
$ paste t.tmp.*
A B     A D
1 C     1 D
2 C     2 D
3 C     3 D
4 C     4 D

修改

更高效(仅为每个组构建一​​次文件名)并且更加健壮(避免在我们离开时关闭它们时打开过多文件的机会)---谢谢,Ed Morton:

awk '$1 == "A" { close(out); out = "t.tmp." ++n} { print > out }' input.txt

(上面假设第一条记录包含模式。如果没有,可以在BEGIN块中初始化。)

答案 1 :(得分:1)

您可以使用单awk

执行此操作
awk 'NR>1 && /^A/{p=1} {if (p) print a[++i], $0; else a[NR]=$0}' OFS='\t' file

A B     A D
1 C     1 D
2 C     2 D
3 C     3 D
4 C     4 D

答案 2 :(得分:0)

使用csplitpaste

$ csplit -zsf file infile.txt '/A/' {*}
$ paste file*
A B     A D
1 C     1 D
2 C     2 D
3 C     3 D
4 C     4 D

来自man csplit

  

csplit - 将文件拆分为由上下文行确定的部分

     

-z, - elide-empty-files   删除空输出文件

     

-s, - quiet, - silent   不打印输出文件大小的计数

     

-f, - prefix = PREFIX   使用PREFIX而不是' xx'

     

{*}尽可能多次重复上一个模式

答案 3 :(得分:-1)

使用gnu awk多行记录 - 适用于任意数量的模式 - 假设长度相等的列

pat=A
awk -vpat=$pat -F'\n' '
BEGIN {RS="(^|\n)"pat" "}
NR>1{
  nr=NR-2
  fld[nr][0]=pat" "$1
  for(i=2; i<=NF; ++i)
    fld[nr][i-1]=$i
}
END {
  for(i=0; i < NF; ++i) {
    for(j=0; j < NR-1; ++j)
      printf("%s%s", j?"\t":"", fld[j][i])
    printf("\n")
  }
}
'

输入

A B
1 C
2 C
3 C
4 C
A D
1 D
2 D
3 D
4 D
A X
1 X
3 X
5 X
7 X

输出

A B     A D     A X
1 C     1 D     1 X
2 C     2 D     3 X
3 C     3 D     5 X
4 C     4 D     7 X

答案 4 :(得分:-2)

如果你正在读这篇文章,并想知道为什么它被投票,那只是一些小丑是幼稚的,因为我指出了一些问题和方法,他们可以改善他们以前的答案,downvote与这个技术优点无关回答。这是解决此问题的 惯用awk解决方案。

$ awk -v OFS='\t' '
    $1 == "A" { numRows=0; ++numCols }
    { val[++numRows,numCols] = $0 }
    END {
        for (rowNr=1;rowNr<=numRows;rowNr++) {
            for (colNr=1;colNr<=numCols;colNr++) {
                printf "%s%s", val[rowNr,colNr], (colNr<numCols ? OFS : ORS)
            }
        }
    }
' file
A B     A D
1 C     1 D
2 C     2 D
3 C     3 D
4 C     4 D