2017-06-26 39 views
1

假定文本文件file包含多行數字範圍。每個範圍的下限和上限用短劃線分開,並且對各個範圍進行排序(即,範圍101-297在1299-1314之前)。評估bash中數字範圍的重疊

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

我怎樣才能在慶典確認,如果一個或多個這些數量範圍的重疊?

在我看來,所有需要的似乎是迭代地執行跨相鄰行的整數比較。各個整數比較可能看起來像這樣的事情:

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

我懷疑,但是,這種比較也可以通過AWK來完成。

注意:理想情況下,代碼不僅可以確定是否有任何範圍與其直接後繼範圍重疊,而且哪個範圍是重疊範圍。

回答

1

嘗試在AWK。

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

這裏製作 - (破折號)作爲字段分隔符,然後檢查是否爲q變量是NOT NULL,它的值大於當前行的第一個字段($ 1)爲是,則打印該行(如果你想要打印上一行,我們也可以這樣做),現在創建/重新分配變量Q的值到當前行的最後一個字段的值。

編輯:根據OP用戶想要得到上一行,所以現在也改變它。

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

優秀的答案。是的,你將如何修改打印語句來打印前一行而不是當前行? –

+0

@MichaelGruenstaeudl:請現在檢查我編輯的答案,讓我知道如果這可以幫助你。 – RavinderSingh13

+0

很好用!謝謝。 –

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 
+0

謝謝你,但你有沒有測試此代碼?看起來,循環似乎並沒有遍歷整個範圍。 'for((i = 1; i <$ {#ranges [@]}; i + = 1));做echo $ i;完成' –

+0

好吧,它似乎在第一行數組初始化上缺少的數組初始化與批註線:'範圍=($(<文件))'而不是'ranges = $(<文件)' –

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