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

问题描述 投票:0回答:5

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

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)

bash awk
5个回答
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

1
投票

awk with paste:

$ 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块中初始化。)


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, - else-empty-files删除空输出文件

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

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

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


-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

-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
© www.soinside.com 2019 - 2024. All rights reserved.