我想转置一个如下所示的文件,其中第二列和每个列标题(B4,B3,E0)可以取两个值。我希望B4 B3 ...
的所有值都在一行中。这意味着B4 B3 E0
将是单独的行。
如何用例如awk sed或python。我可以在python中进行简单的转置,但我不明白如何解决这个特殊的问题。
输入:第2列和第3列具有相同的列名,即B4,类似第4和第5列具有相同的列名,即B3,依此类推。当我们转置两个对应于B4的值时,应该像{{{{{{{ 1}}。它应该在一条线上。输入文件包含20多列和2000行。
输入:
12 13 13 14 13 13 12 13 13 13 12 13
期望的输出:
ID B4 B3
1 12 13 19 21
2 13 14 19 21
3 13 13 19 21
4 12 13 19 19
5 13 13 18 19
6 12 13 19 21
这就是我的尝试:
ID 1 1 2 2 3 3 4 4 5 5 6 6
B4 12 13 13 14 13 13 12 13 13 13 12 13
B3 19 21 19 21 19 21 19 19 18 19 19 21
还尝试了python -c "import sys; print('\n'.join(' '.join(c) for c in zip(*(l.split() for l in sys.stdin.readlines() if l.strip()))))" < input file>output file
代码,但没有运气。
答案 0 :(得分:3)
awk 解决方案:
awk 'NR==1{ for (i=1; i<=NF; i++) col[i]=$i }
NR>1{
col[1]=sprintf("%s %s %s",col[1],$1,$1); j=1;
for (i=2; i<=NF; i+=2) {
j++; col[j]=sprintf("%s %s %s",col[j],$i,$(i+1))
}
}
END { len=length(col); for (i=1; i<=len; i++) print col[i] }' input
输出:
ID 1 1 2 2 3 3 4 4 5 5 6 6
B4 12 13 13 14 13 13 12 13 13 13 12 13
B3 19 21 19 21 19 21 19 19 18 19 19 21
NR==1{ for(i=1;i<=NF;i++) col[i]=$i }
- 在第1行累积列名称
col[1]=sprintf("%s %s %s",col[1],$1,$1)
- 连接第一个ID
列的值
j++; col[j]=sprintf("%s %s %s",col[j],$i,$(i+1))
- 连接每个下一列的值(每列两个值)
答案 1 :(得分:1)
此python代码解决了您的问题
import sys
header = sys.stdin.readline().strip().split()
transposed = [[item] for item in header]
for line in sys.stdin.readlines():
items = line.strip().split()
transposed[0].append(items[0])
for i in range(1, len(transposed)):
transposed[i].extend(items[2*i - 1: 2*i + 1])
for line in transposed:
print(" ".join(line))