linux - 如何比较bash中的2个范围列表?

标签 linux bash awk range genetics

使用 bash 脚本(Ubuntu 16.04),我正在尝试比较 2 个范围列表:file1 中任何范围内的任何数字是否与 file2 中任何范围内的任何数字一致?如果是这样,打印第二个文件中的行。在这里,我将每个范围作为 2 个制表符分隔的列(在文件 1 中,第 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:改进了范围重叠测试。

EDIT 2:重用了 RomanPerekhrest 提出的出色优化(未设置 file2 中已打印的范围)。当范围重叠的可能性很高时,性能应该更好。

编辑 3:与 RomanPerekhrest 提出的 awk 版本的性能比较(修复了最初的小错误后):awk 介于 10 和在这个问题上比 bash 快 20 倍。如果性能很重要,而您在 awkbash 之间犹豫不决,则首选:

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

关于linux - 如何比较bash中的2个范围列表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53694324/

相关文章:

linux - 如何将 C 字符串数组传递给线程 (pthreads)

python - 使用子进程运行多个 bash 命令

linux - 一个月中每一天的两次之间的日期值

awk 提取字符串的一部分,与数字进行比较,完整输出原始行

LINUX:如何输出 SQL 脚本中使用的表

parsing - awk中的字段分隔符

linux - 使用 epoll 的客户端连接

linux - Ubuntu 12.04 上带有 mod_jk 的 Tomcat 7 和 Apache2

c - 重定向歧义

bash - CentOS,将 ipV6 短格式转换为长格式