2011-06-20 57 views
1

我有两个文件,这是不同的行:比较两个文件

文件1:

31.32 29.15 46.77 106.40 11370 
25.81 40.82 25.67 30.08 16365 
27.11 42.32 14.48 50.04 18310.7 
26.48 42.34 12.65 62.78 19607.5 
24.48 46.00 17.16 11.86 22087.2 
26.75 43.91 29.65 55.81 24032.7 
30.91 34.85 15.25 50.93 26703 
25.24 41.62 16.54 51.57 38032.9 
23.48 41.97 17.33 50.88 48981.2 
24.16 39.34 16.99 50.86 77513.4 
22.90 41.59 19.76 50.31 135803 
19.98 43.52 20.58 45.65 747049 
19.96 43.64 20.43 45.37 809913 
19.93 43.75 20.41 45.33 863931 

和文件2:

12.4 -32.1 39.1 -44.9 135497.688 
8.6 -38.6 39.3 -44.8 48981.191 
1.0 -45.0 0.0  -54.0 45928.445 
13.9 -70.1 39.4 -44.8 26702.982 

我想这两个文件进行比较和输出:

文件3

13.9 -70.1 30.91 34.85 39.4 -44.8 15.25 50.93 26702.982 
8.6 -38.6 23.48 41.97 39.3 -44.8 17.33 50.88 48981.191 

问题是两个文件中的各个列值不完全匹配。但是,如果它们在某些误差范围内匹配(例如,+/- 1),那将会很好。


诠释其中的文件3的值来自使用F/R/C的文件/行/列:

13.9 -70.1 30.91 34.85 39.4 -44.8 15.25 50.93 26702.982 
2/4/1 2/4/2 1/7/1 1/7/2 2/4/3 2/4/4 1/7/3 1/7/4 2/4/5 

8.6 -38.6 23.48 41.97 39.3 -44.8 17.33 50.88 48981.191 
2/2/1 2/2/2 1/9/1 1/9/2 2/2/3 2/2/4 1/9/3 1/9/4 2/2/5 

但是:

  • 为什么没有条目文件2中的其他行?
  • 为什么没有文件1中其他行的条目?
  • File 1 Row 7中的值与File 2 Row 4中的值有什么关系?
  • File 1 Row 9中的值如何与File 2 Row 2中的值相关?
  • 为什么文件1的列5不在输出中?
  • 文件1第5列与文件2的第5列结合在一起,公差为±1?
+2

能否请您发表表现出你的问题的实质更可读,最小的例子吗? –

+0

这些值代表什么,以及文件#1中的内容是否构成文件#2? –

+0

我想要输出文件作为文件#3,该文件是从文件#1和文件#2的可比较的列#5生成的,但问题是两个文件中的各个列值不完全匹配。你有什么主意吗 ? –

回答

2
awk ' 
    function close_enough(v1, v2, delta) { 
     delta = v1 - v2 
     return (-1 <= delta && delta <= 1) 
    } 
    NR == FNR { 
     key[$NF] = $0 
     next 
    } 
    { 
     for (val in key) { 
      if (close_enough($NF,val)) { 
       split(key[val], arr) 
       print arr[1], arr[2], $1, $2, arr[3], arr[4], $3, $4, val 
      } 
     } 
    } 
' file2 file1 | column -t > file3 
+0

+1。令人印象深刻! :)。我写了一个程序,它只是程序大小的两倍。 –

+1

起初我以为你的解决方案不行。然后我跑了它,看到它得到了正确的结果。然后我觉得你很幸运。然后,我更多地研究它,并得出结论,这绝对是辉煌的! – grok12

+0

谢谢@glen你的脚本工作正常,超级... –

4

此:

(LC_ALL=C; join -1 5 -2 5 \ 
    <(<file1 awk '{printf "%s %s %s %s %d\n",$1,$2,$3,$4,int($5+0.5);}' | sort -nk5)\ 
    <(<file2 awk '{printf "%s %s %s %s %d\n",$1,$2,$3,$4,int($5+0.5);}' | sort -nk5) 
) | awk '{print $2, $3, $6, $7, $4, $5, $8, $9, $1}' 

将产生你的输入这样的:

13.9 -70.1 30.91 34.85 39.4 -44.8 15.25 50.93 26703 
8.6 -38.6 23.48 41.97 39.3 -44.8 17.33 50.88 48981 

最后一列是圆形的。

更紧凑的形式:

cmd() { 
    awk '{printf "%s %s %s %s %d\n",$1,$2,$3,$4,int($5+0.5);}' | sort -nk5 
} 
(LC_ALL=C; join -1 5 -2 5 <(<file1 cmd) <(<file2 cmd)) |\ 
awk '{print $2, $3, $6, $7, $4, $5, $8, $9, $1}' 
+0

+1 - 非常有创意地使用shell命令。 – kobame

+0

谢谢@ jm666,你的脚本也在工作,这是一个令人印象深刻的shell脚本 –

0

只有AWK。

awk ' 
NR==FNR {a[int($5+0.5)] = $0; next} 
a[int($5+0.5)] {$0 = a[int($5+0.5)] " " $0; print $6,$7,$1,$2,$8,$9,$10}' file1 file2 

如果你需要它来进行排序,将输出到sort

+0

好,简短的代码和更简单 –