我在这里检查了合并时的其他线程,但是它们似乎主要是关于合并文本,并不是我所需要的,或者至少我无法找到一种将他们的解决方案与我自己的问题联系起来的方法。
我有10多个输入文件,每个输入文件由两列数字组成(将它们视为图形的x,y数据点)。目标:
将此示例考虑为3个文件:
y1.dat
25 16
27 18
y2.dat
24 10
27 9
y3.dat
24 2
29 3
根据上述目标,我应该能够将它们合并到一个文件中,并输出:
final.dat
24 12
25 16
27 27
29 3
到目前为止,我有以下内容:
#!/bin/bash
loops=3
for i in `seq $loops`; do
if [ $i == 1 ]; then
cp -f y$i.dat final.dat
else
awk 'NR==FNR { arr[NR] = $1; p[NR] = $2; next } {
for (n in arr) {
if ($1 == arr[n]) {
print $1, p[n] + $2
n++
}
}
print $1, $2
}' final.dat y$i.dat >> final.dat
fi
done
输出:
25 16
27 18
24 10
27 27
27 9
24 12
24 2
29 3
仔细检查,很明显我有原始x值的副本。
问题是我的脚本需要首先打印所有x值,然后才能将它们添加在一起以进行输出。但是,我不知道如何返回并删除添加相加所需的带有旧x值的行。
如果我盲目使用uniq,我不知道是删除了旧的x值还是新的x值。使用awk'!duplicate [$ 1] ++',删除的行顺序在循环中是相反的,因此它可以在第一个循环中正确删除,但在此之后是错误的。
长期从事此工作,将不胜感激。谢谢!
答案 0 :(得分:2)
我假设您已经在计算之前将所有文件合并为一个文件。完成后,脚本就很简单了:
awk '{ if ( $1 != "" ) { coord[$1]+=$2 } } END { for ( k in coord ) { print k " " coord[k] } }' input.txt
希望有帮助!
if ( $1 != "" ) { coord[$1]+=$2 }
此行将针对您输入中的每一行执行。首先将检查X是否存在值,否则将忽略该行。如果文件有空行,这有助于忽略空行。被执行的代码块: coord [$ 1] + = $ 2 是脚本的核心,并创建一个字典,其中X是每个条目的键,并且同时将找到的Y的每个值相加
END { for ( k in coord ) { print k " " coord[k] }
awk遍历文件中的所有行之后,将执行此块。它将简单地从字典中获取每个键并打印,然后打印一个空格,最后是找到的所有值的总和,换句话说,就是该特定键的值。
答案 1 :(得分:0)
使用Perl单线版
> cat y1.dat
25 16
27 18
> cat y2.dat
24 10
27 9
> cat y3.dat
24 2
29 3
> perl -lane ' $kv{$F[0]}+=$F[1]; END { print "$_ $kv{$_}" for(sort keys %kv) }' y*dat
24 12
25 16
27 27
29 3
>