Bash

將逗號分隔的數字列表轉換為連字元列表或範圍

  • May 8, 2021

我有一個逗號分隔的數字字元串,如下所示:

1,2,3,5,6,7,8,9,12,14

我正在尋找一個在bash腳本中使用的命令,該命令可以將相鄰的數字組合成範圍/連字元的條目,如下所示:

1-3,5-9,12,14

保證初始字元串按升序排序。

使用 perl:

perl -pe 's/\b(\d+)(?{$q=$1+1})(?:,(??{$q})\b(?{$p=$q++})){2,}/$1-$p/g'

這是通過(?{...})and表達式使用嵌入 perl 程式碼的正則(??{...})表達式;第一個只是評估嵌入的程式碼,而第二個使用它返回的值作為模式。請參閱perlre(1)完整說明。

如果您還想要兩個數字的範圍(例如-> ) ,請將{2,}量詞替換為。+``1,2,7``1-2,7

這是一個簡短的awk腳本,它遍歷以逗號分隔的排序整數列表並填充兩個數組ab, 同時這樣做。

a數組將包含每個單調遞增整數範圍的起始整數,同時b將包含相應的結束整數。程式碼中的變數n保存找到的範圍的數量。

BEGIN {
   OFS = FS = ","
}

{
   n = 0

   a[++n] = $1
   for (i = 1; i < NF; ++i)
       if ($i != $(i+1) - 1) {
           b[n] = $i
           a[++n] = $(i+1)
       }
   b[n] = $NF

   $0 = ""

   for (i = 1; i <= n; ++i)
       if (a[i] == b[i])
           $i = a[i]
       else
           $i = sprintf("%d-%d", a[i], b[i])

   print
}

輸出是通過遍歷n找到的不同範圍並構造一個記錄來創建的,其中每個欄位是單個整數(對於長度為 1 的範圍)或表示範圍開始和結束的字元串。

對您提供的數據進行測試,從文件中讀取數據:

$ awk -f script.awk file
1-3,5-9,12,14

您顯然可以使用標準輸入中的字元串來輸入它,如下所示:

$ awk -f script.awk <<<"1,2,3,5,9,10,11,12,13"
1-3,5,9-13

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