Bash

將序列中的一系列逗號分隔數字折疊到Beginning-End

  • May 8, 2021

問題我正在嘗試解決/增強提供數字序列的 BASH 腳本:我正在使用拓撲感知工具 (lstopo-no-graphics) 來提取物理處理器編號,以用於輸入到 numactl 以進行處理器綁定。

L3 L#4 共享高速記憶體物理核心的範例輸出

lstopo-no-graphics --no-io|sed -n "/L3 L#3/,/L3/p"|grep -v "L3\|L2"|tr -s '[:space:]'|cut -d " " -f4|grep -o "[0-9]*"|sort -g|tr '\n' ','|sed '$s/,$//'

產生數字系列字元串:

32,33,34,35,36,37,38,39,96,97,98,99,100,101,102,103

一切都很好,我將這個系列用於numactl --physcpubin=32,33,34,35,36,37,38,39,96,97,98,99,100,101,102,103، 我希望能夠將序列折疊為numactl --physcpubin=32-39,96-103‌ ,希望在連續時將多個逗號分隔的數字序列折疊為一個“an”系列,每個序列逗號分隔。

我對現有的 bash 腳本沒有問題,如果有人有任何想法,只是在尋找更乾淨的實現?

將此另存為**range.awk**.

{
   for(i=2;i<=NF+1;i++){     #Visit each number from the 2nd on
       if($i==$(i-1)+1){
           if(f=="")f=$(i-1) #Candidate to first number of a range
           continue
       }
       printf("%s%s%s%s", f, (f!="" ? "-" : ""), $(i-1), (i>NF ? RS : FS))
       f="" #Unset the candidate
   }
}

執行它:awk -F, -f range.awk

或者複製粘貼折疊的單行:

awk -F, '{for(i=2;i<=NF+1;i++){if($i==$(i-1)+1){if(f=="")f=$(i-1);continue}printf("%s%s%s%s",f,f!=""?"-":"",$(i-1),i>NF?RS:FS);f=""}}'

我沒有對欄位分隔符進行硬編碼,因此必須使用-F.

範例輸出:

$ awk -F, -f range.awk <<< 32,33,34,35,36,37,38,39,96,97,98,99,100,101,102,103
32-39,96-103
$ awk -F, -f range.awk <<< 0,1,2,5,8,9,11
0-2,5,8-9,11
$ awk -F, -f range.awk <<< 4
4

引用自:https://unix.stackexchange.com/questions/647023