相关问题:https://stackoverflow.com/posts/18164848
输入文件input.txt是带有
的制表符分隔的unicode txta A e f m
b B g h
c C i j
b B k l
我希望通过第一列和第二列匹配并合并。所以我想用
获取output.txta A e f m
b B g h k l
c C i j
代码必须检测输入中的最大列数。由于在这个例子中它是5,所以从第6列放入“k l”。
实际上,当他们都是数字时,我几乎设法使用Matlab来做到这一点。但是哦,当它们是字母时,Matlab在处理unicode方面非常糟糕,虽然我读了关于如何在Matlab中处理unicode的stackoverflow我放弃了。所以我现在转向python。
https://stackoverflow.com/posts/18164848的Nirk回复说以下一行会这样做。
awk -F \ t'{a = $ 1“\ t”$ 2; $ 1 = $ 2 = “”; x [a] = x [a] $ 0} END {for(y in x)print y,x [y]}'
但是这段代码似乎没有指定输入和输出文件。
答案 0 :(得分:3)
awk是基于管道的linux命令。要提供输入文件并获取输出,您可以这样做: awk -F \ t'{a = $ 1“\ t”$ 2; $ 1 = $ 2 = “”; x [a] = x [a] $ 0} END {for(y in x)print y,x [y]}'< INPUT.TXT> OUTPUT.TXT
但是,上面的awk程序很难匹配你需要的东西“代码必须检测输入中的最大列数。因为在这个例子中它是5,所以”kl“从第6列开始。”。< / p>
你可以尝试这个python程序:
max_value_fields = 0
values = dict()
with file("input.txt") as f:
keys = []
for line in f:
line = line.strip()
fs = line.split('\t')
key = '%s\t%s' % (fs[0], fs[1])
if key not in values:
values[key] = list()
keys.append(key)
values[key].append(fs[2:])
value_fields = len(fs) - 2
if value_fields > max_value_fields:
max_value_fields = value_fields
with file("output.txt", 'w+') as f:
for key in keys:
fields = [key]
for value_list in values[key]:
fields.extend([value for value in value_list])
fields.extend(['' for i in xrange(max_value_fields - len(value_list))])
print >> f, '\t'.join(fields)
答案 1 :(得分:2)
我会读取数据两次:第一次传递用于识别最大列数,然后在第二次传递中合并行。在END中打印结果(基本上是随机顺序)。
awk -f script.awk infile infile > outfile
$ cat script.awk
# BEGIN block: separators
BEGIN { FS = OFS = "\t" }
# Loop #1: detect maximum number of columns
NR == FNR { max = NF > max ? NF : max ; next }
# Loop #2: merge rows
{
k = $1 FS $2
if (k in a) {
for (i = 3; i <= NF; i++) {
a[k] = a[k] OFS $i
}
} else {
NF = max
a[k] = $0
}
}
# END block: Print results
END { for (i in a) print a[i] }
答案 2 :(得分:1)
试试这个:
awk '{x=$1FS$2;$1=$2="";a[x]=a[x]?a[x]FS$0:$0}END{for(x in a) print x,a[x]}' input.txt