我是Unix的新手,并且无法根据带有连字符索引的字段加入两个制表符分隔的文本文件。例如:
file1.txt
33-47 10 22 -99 10
33-48 15 22 165 456
33-101 10 22 -99 15.8
33-126 10 22 -99 15.5
34-133 10 22 -99 13
40-109 10 22 -99 12
41-102 88 21 -99 20
45-169 54 214 -99 4
100-11 652 524 87 5
101-25 45 54 153 8
101-26 1285 12 155 9.5
和
file2.txt
1 5432 545 33-101
1 5524 5420 33-126
0 855520 52220 33-47
0 5463 5420 34-133
0 5563 5423 40-109
1 6098 -99 40-109
本质上,文件1是一个查找表,我想将文件1的匹配行追加到文件2,以便创建一个完整的变量表,即:
file3.txt (expected)
1 5432 545 33-101 10 22 -99 15.8
1 5524 5420 33-126 10 22 -99 15.5
0 855520 52220 33-47 10 22 -99 10
0 5463 5420 34-133 10 22 -99 13
0 5563 5423 40-109 10 22 -99 12
1 6098 -99 40-109 10 22 -99 12
我正在使用Cygwin,并尝试首先按字母顺序排序字段,通常使用LC_COLLATE = C语言环境,以及许多awk NR == FNR命令,但我仍然得到一个空白的outfile。
这是全新的,非常令人沮丧。如果可以的话请帮忙!
谢谢!
答案 0 :(得分:1)
这对我有用,但我不在Cygwin上:
awk 'NR==FNR{info[$1]=gensub(/[^\t]*\t/,"",1)} NR!=FNR{printf"%s\t%s\n",$0,info[$NF]}' file1.txt file2.txt
我相信有人可以改进......
答案 1 :(得分:1)
我会 非常 对您了解join
如何工作感兴趣。
这是一种非常丑陋的方式:
a='{split($f, a, /-/); $f = sprintf("%05d%05d", a[1], a[2]); print}'
join -1 4 -2 1 -o 1.1 1.2 1.3 0 2.2 2.3 2.4 2.5 2.6 2.7 2.8 \
<(awk -v f=4 "$a" file2.txt | sort -k4,4) |
<(awk -v f=1 "$a" file1.txt | sort) \
awk 'BEGIN {OFS = "\t"} {$4 = substr($4, 1, 5) + 0 "-" substr($4, 6, 5) + 0; print}'
输出:
0 855520 52220 33-47 10 22 -99 10
1 5432 545 33-101 10 22 -99 15.8
1 5524 5420 33-126 10 22 -99 15.5
0 5463 5420 34-133 10 22 -99 13
0 5563 5423 40-109 10 22 -99 12
1 6098 -99 40-109 10 22 -99 12
如果您省略了-o
输出规范(并在最终$4
中将字段从$1
更改为awk
),从而缩短命令,这就是输出看起来像(普通字段优先):
33-47 0 855520 52220 10 22 -99 10
33-101 1 5432 545 10 22 -99 15.8
33-126 1 5524 5420 10 22 -99 15.5
34-133 0 5463 5420 10 22 -99 13
40-109 0 5563 5423 10 22 -99 12
40-109 1 6098 -99 10 22 -99 12
上面的工作方法是在键字段中左边填充数字并删除连字符,然后再撤消它。这允许简单的词法排序。
我很想使用sort -V
(版本排序)而不是使用填充技术。它给出了正确的排序顺序,但join
不同意。