如何将连续数字折叠到范围内?

don*_*sti 10 awk perl text-processing numeric-data

给定一个包含唯一数字的排序输入文件(或命令输出),每行一个,我想将所有连续数字的运行折叠到范围内,这样

n
n+1
...
n+m
Run Code Online (Sandbox Code Playgroud)

变成

n,n+m
Run Code Online (Sandbox Code Playgroud)

输入样本:

2
3
9
10
11
12
24
28
29
33
Run Code Online (Sandbox Code Playgroud)

预期输出:

2,3
9,12
24
28,29
33
Run Code Online (Sandbox Code Playgroud)

cta*_*ac_ 10

随着dc对脑力锻炼:

dc -f "$1" -e '
[ q ]sB
z d 0 =B sc sa z sb
[ Sa lb 1 - d sb 0 <Z ]sZ
lZx
[ 1 sk lf 1 =O lk 1 =M ]sS
[ li p c 0 d sk sf ]sO
[ 2 sf lh d sj li 1 + !=O ]sQ
[ li n [,] n lj p c 0 sf ]sM
[ 0 sk lh sj ]sN
[ 1 sk lj lh 1 - =N lk 1 =M ]sR
[ 1 sf lh si ]sP
[ La sh lc 1 - sc lf 2 =R lf 1 =Q lf 0 =P lc 0 !=A ]sA
lAx
lSx
'
Run Code Online (Sandbox Code Playgroud)

  • @don_crissti,如果您遇到此类问题,请在 [codegolf.se](https://codegolf.stackexchange.com/) 上发布相同的问题,然后有人会在 Brainf**k 中实现它。 (3认同)
  • 这是那种让你希望你能投两次票的答案...... (2认同)

gle*_*man 8

awk '
    function output() { print start (prev == start ? "" : ","prev) }
    NR == 1 {start = prev = $1; next}
    $1 > prev+1 {output(); start = $1}
    {prev = $1}
    END {output()}
'
Run Code Online (Sandbox Code Playgroud)


小智 5

awk,采用不同的(更像C)方法:

awk '{ do{ for(s=e=$1; (r=getline)>0 && $1<=e+1; e=$1); print s==e ? s : s","e }while(r>0) }' file
Run Code Online (Sandbox Code Playgroud)

同样的事情,甚至更不尴尬:

awk 'BEGIN{
    for(r=getline; r>0;){
        for(s=e=$1; (r=getline)>0 && $1<=e+1; e=$1);
        print s==e ? s : s","e
    }
    exit -r
}' file
Run Code Online (Sandbox Code Playgroud)

  • @steve `getline` 出错时返回 -1 (例如 `EIO`) (2认同)
  • @史蒂夫。这就是为什么 `exit -r` 也可以被删除(awk 将在下一个自动 `getline` 上自行处理),但我希望第二个版本完全不神奇。 (2认同)

JJo*_*oao 5

使用 Perl 替代 eval(抱歉混淆...):

perl -0pe 's/(\d+)\n(?=(\d+))/ $1+1==$2 ? "$1," : $& /ge; 
           s/,.*,/,/g' ex
Run Code Online (Sandbox Code Playgroud)
  • 第一次替换创建用“,”分隔的连续 int 序列的行;
  • 第二次替换,删除中间数字。


Rud*_*diC 1

怎么样

awk '
$0 > LAST+1     {if (NR > 1)  print (PR != LAST)?"," LAST:""
                 printf "%s", $0
                 PR = $0
                }
                {LAST  = $0
                }
END             {print (PR != LAST)?"," LAST:""
                }
' file
2,3
9,12
24
28,29
33
Run Code Online (Sandbox Code Playgroud)