微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

linux – 如何在bash中比较2个范围列表?

使用bash脚本(Ubuntu 16.04),我试图比较2个范围列表:file1中任何范围内的任何数字是否与file2中任何范围内的任何数字一致?如果是这样,请在第二个文件中打印该行.这里我将每个范围作为2个制表符分隔的列(在file1中,第1行表示范围1-4,即1,2,3,4).真实的文件非常大.

文件1:

1 4
5 7 
8 11
12 15

文件2:

3 4 
8 13 
20 24

期望的输出

3 4 
8 13

我最好的尝试是:

awk 'NR=FNR { x[$1] = $1+0; y[$2] = $2+0; next}; 
{for (i in x) {if (x[i] > $1+0); then
{for (i in y) {if (y[i] <$2+0); then            
{print $1, $2}}}}}' file1 file2 > output.txt

这将返回一个文件.

我认为脚本需要使用if-then条件进行范围比较,并遍历两个文件中的每一行.我找到了每个概念的例子,但无法弄清楚如何将它们结合起来.

任何帮助赞赏!

解决方法:

当然,这取决于你的文件有多大.如果它们不足以耗尽内存,您可以尝试这种100%bash解决方案:

declare -a min=() # array of lower bounds of ranges
declare -a max=() # array of upper bounds of ranges

# read ranges in second file, store then in arrays min and max
while read a b; do
    min+=( "$a" );
    max+=( "$b" );
done < file2

# read ranges in first file    
while read a b; do
    # loop over indexes of min (and max) array
    for i in "${!min[@]}"; do
        if (( max[i] >= a && min[i] <= b )); then # if ranges overlap
            echo "${min[i]} ${max[i]}" # print range
            unset min[i] max[i]        # performance optimization
        fi
    done
done < file1

这只是一个起点.有许多可能的性能/内存占用改进.但它们在很大程度上取决于文件的大小和范围的分布.

编辑1:改进了范围重叠测试.

编辑2:重用RomanPerekhrest提出的优秀优化(未设置已从file2打印的范围).当范围重叠的概率很高时,性能应该更好.

编辑3:与RomanPerekhrest提出的awk版本的性能比较(在修复了最初的小错误之后):awk比bash在这个问题上快10到20倍.如果性能很重要且你在awk和bash之间犹豫不决,那么更喜欢:

awk 'NR == FNR { a[FNR] = $1; b[FNR] = $2; next; }
    { for (i in a)
          if ($1 <= b[i] && a[i] <= $2) {
              print a[i], b[i]; delete a[i]; delete b[i];
          } 
    }' file2 file1

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐