问题描述
目标
我有一个长字符串 s
,它代表由逗号和破折号分隔的一系列数字(见下文).当几个数字相互跟随时,两个极端数字被写入并用破折号分隔.例如,系列4,5,6,7
写为4-7
.我的目标是扩展这个字符串,让所有数字都用逗号分隔(4-7
应该变成 4,5,6,7
).
I have a long string s
which represents series of numbers separated by commas and dashes (see below). When several numbers follow each other, the two extreme numbers are written and are separated by a dash. For example, the series 4,5,6,7
is written as 4-7
. My goal is to expand this string to have all numbers separated by comas (4-7
should become 4,5,6,7
).
我做了什么
这是一个字符串的例子
s="4092-4093,4095-4097,4104,4107,4111,4125-4127"
我想首先用 {4..7}
替换 4-7
类型的模式(使用 sed 反向引用)
I wanted to first replace the patterns of the type 4-7
by {4..7}
(using sed backreferening)
a="$(echo $s | sed 's/\([0-9]*\)-\([0-9]*\)/{\1..\2}/g')"
然后计算字符串以展开大括号
and then evaluate the string to expand the braces
b="$(eval echo $a)"
但是,当我运行最后一个命令时,扩展是以阶乘方式"完成的(导致 RAM 使用量激增).
However, when I run this last command, the expansion is done "in a factorial way" (leading to an explosion of the RAM usage).
问题
如何将字符串中 4-7
类型的模式替换为 4,5,6,7
?
How can I replace the patterns of the kind 4-7
into 4,5,6,7
in my string?
版本
我使用 Mac OS X 10.11.3
并使用 Terminal 2.6.1 (361.1)
推荐答案
一个使用 GNU awk 的答案,它应该在大量输入时表现更好:
An answer using GNU awk which should perform better with large inputs:
#!/usr/bin/env gawk -f
{
while ( match($0, /([0-9]+)-([0-9]+)/, arr) ) {
s = arr[1]
for (i=int(arr[1]) + 1; i<=int(arr[2]); i++) {
s = s "," i
}
gsub(arr[1] "-" arr[2], s)
}
print
}
或者,在纯 bash 中(使用少量数据获得更好的性能):
Alternately, in pure bash (for better performance with small amounts of data):
s="4092-4093,4095-4097,4104,4107,4111,4125-4127"
re='([0-9]*)-([0-9]*)'
while [[ $s =~ $re ]]; do
eval_str="printf -v replacement '%s,' {${BASH_REMATCH[1]}..${BASH_REMATCH[2]}}"
eval "$eval_str"
replacement=${replacement%,}
s=${s//${BASH_REMATCH[0]}/$replacement}
done
这篇关于如何在 Bash 中将 `4-7` 替换为 `4,5,6,7`的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!