我知道以前有人问过类似的问题(例如,在Unix上连接文本文件中的多个字段(,但我似乎找不到解决我特定问题的方法。
我的文件结构如下(col1=ID,col2=时间增量,col3=数据(:
head file1
14.000119 0 yes
14.000119 69 yes
14.000119 168 no
14.000119 259
14.000119 431
14.000119 888 yes
head file2
14.000119 0 no
14.000119 70 no
14.000119 169 yes
14.000119 262
14.000119 456
14.000119 525
我的目标是首先根据 ID 和时间第二连接这两个文件。但是,还必须添加不相等的时间值,并且数据列 (col3( 必须放在输出文件中的正确列中。
期望输出:
14.000119 0 yes no
14.000119 69 yes
14.000119 70 no
14.000119 168 no
14.000119 169 yes
14.000119 259
14.000119 262
14.000119 431
14.000119 456
14.000119 525
14.000119 888 yes
列按制表符分隔。我知道有一个awk或join的解决方案,但我似乎不能正确。我最接近的是使用
awk -F\t '{
o1=$1;o2=$2
$1=$2="";gsub("t","")
_[o1 FS o2]=_[o1 FS o2] FS $0
} END {
for(i in _) print i,_[i]
}' file1 file2 | sort -k1,1 -k2,2 -n
这给了我:
14.000119 0 yes no
14.000119 69 yes
14.000119 70 no
14.000119 168 no
14.000119 169 yes
14.000119 259
14.000119 262
14.000119 431
14.000119 456
14.000119 525
14.000119 888 yes
但如您所见,如果 file1 中同一键的值不为空,则数据值仅在正确的列中填充(file2 为 4th(。
使用join和一些解决方法解决了它!
join -j1 -a 1 -a 2 -e '' -o '0,1.4,2.4' -t $'t'
<(<file1 awk -F\t '{print $1"-"$2 "t" $0}' | sort -k1,1)
<(<file2 awk -F\t '{print $1"-"$2 "t" $0}' | sort -k1,1)
| sed 's/-/t/g' | sort -k1,1 -k2,2 -n
说明:-j1
: 连接第一个字段-a 1 -a 2
:还打印两个文件中不可配对的行-e ''
:用空字段填充空白-o 0,1.4,2.4
:
输出文件1和文件2的第一个字段以及第4个字段-t $'t'
:制表符
分隔<(<file1 ...)
打印
前两列,中间有"-"而不是制表符, 将前两列"压缩"为一列(连接仅适用于一列(sed 's/-/t/g'
:将破折号恢复为选项卡sort -k1,1 -k2,2 -n
:现在输出再次包含 4 列,按第一列和第二列排序
使用 GNU awk 表示数组的数组和sorted_in:
$ cat tst.awk
BEGIN { FS=OFS="t" }
{ vals[$1][$2][ARGIND] = $3 }
END {
PROCINFO["sorted_in"] = "@ind_num_asc"
for (id in vals) {
for (time in vals[id]) {
print id, time, vals[id][time][1], vals[id][time][2]
}
}
}
$ awk -f tst.awk file1 file2
14.000119 0 yes no
14.000119 69 yes
14.000119 70 no
14.000119 168 no
14.000119 169 yes
14.000119 259
14.000119 262
14.000119 431
14.000119 456
14.000119 525
14.000119 888 yes
有了awk
和sort
的一点帮助,怎么样:
awk -F't' '
NR==FNR {a[$1"t"$2] = $3; next}
{a[$1"t"$2] ? a[$1"t"$2] = a[$1"t"$2]"t"$3 : a[$1"t"$2] = "t"$3}
END {for (i in a) print i"t"a[i]}
' file1 file2 | sort -k1,1n -k2,2n
结果:
14.000119 0 yes no
14.000119 69 yes
14.000119 70 no
14.000119 168 no
14.000119 169 yes
14.000119 259
14.000119 262
14.000119 431
14.000119 456
14.000119 525
14.000119 888 yes