Вместо этого с помощью zsh
вы можете определить такую функцию, как:
reduce() {
local i=1
argv=(${(nus:,:)1}) # split $1 on ",", numerically sort and remove dups
while ((i < $#)) {
if ((${argv[i]#*-} + 1 == ${argv[i+1]%-*})) {
argv[i]=${argv[i]%-*}-${argv[i+1]#*-}
argv[i+1]=()
} else {
((i++))
}
}
print ${(j:,:)@}
}
Который также будет принимать диапазоны на вход:
$ reduce 1,2,3,5,6,7,8,9,12,14
1-3,5-9,12,14
$ reduce 1,2,3,5-7,8,9-11,12,13-20
1-3,5-20
$ reduce 5,2,4,5,6
2,4-6
Обратите внимание, что это не будет работать должным образом, если входные данные имеют перекрывающиеся диапазоны:
$ reduce 1-3,2
1-3,2
$ reduce 1-3,2-4
1-3,2-4
Из bash
вы бы определили функцию как:
reduce() { zsh -c '
i=1
argv=(${(nus:,:)1}) # split $1 on ",", numerically sort and remove dups
while ((i < $#)) {
if ((${argv[i]#*-} + 1 == ${argv[i+1]%-*})) {
argv[i]=${argv[i]%-*}-${argv[i+1]#*-}
argv[i+1]=()
} else {
((i++))
}
}
print ${(j:,:)@}' zsh "$@"
}