评估bash中数字范围的重叠

时间:2017-06-26 13:41:36

标签: bash for-loop awk range comparison

假设文本文件file包含多行数字范围。每个范围的下限和上限用短划线分隔,各个范围进行排序(即,范围101-297在1299-1314之前)。

$cat file
101-297
1299-1314
1301-5266
6898-14503

如果这些数字范围中的一个或多个重叠,我如何在 bash 中确认?

在我看来,所需要的只是迭代地在相邻行之间执行整数比较。单个整数比较可能如下所示:

if [ "$upperbound_range1" -gt "$lowerbound_range2" ]; then
    echo "Overlap!"
    exit 1
fi

但我怀疑,这种比较也可以通过 awk 来完成。

注意:理想情况下,代码不仅可以确定任何范围是否与其直接后继范围重叠,还可以确定哪个范围是重叠范围。

3 个答案:

答案 0 :(得分:1)

尝试使用awk。

awk -F"-" 'Q>=$1 && Q{print}{Q=$NF}'   Input_file

在这里 - (破折号)作为字段分隔符,然后检查名为Q的变量是否为NOT且它的值是否大于当前行的第一个字段($ 1)为是然后打印该行(如果要打印上一行)我们也可以这样做),现在创建/重新分配变量Q的值到当前行的最后一个字段的值。

编辑:根据OP用户想要获取上一行,现在也将其更改为现在。

awk -F"-" 'Q>=$1 && Q{print val}{Q=$NF;val=$0}'  Input_file

答案 1 :(得分:1)

你可以这样做:

$ awk -F"-" '$1<last_2 && NR>1 {printf "%s: %s: Overlap\n", last_line, $0} 
                             {last_line=$0; last_2=$2}' file
1299-1314: 1301-5266: Overlap

答案 2 :(得分:0)

如果范围按下限排序,并且范围重叠,则重叠范围将是后继范围。

ranges=( $(<file) )

# or ranges=(101-297 1299-1314 1301-5266 6898-14503)

for ((i=1;i<${#ranges[@]};i+=1)); do
    range=${ranges[i-1]}
    succesorRange=${ranges[i]}
    if ((${range#*-}>=${succesorRange%-*})); then
        echo "overlap $i $range $succesorRange"
    fi
done