我有一个非常简单的问题,但我发现很难解决这个问题。 我有两个很长的数据列,我想将它分成几列。每次在第一列中找到特定字符串时,脚本应该开始将数据写入新列: 输入:
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)
答案 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)
使用csplit
和paste
$ 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