目标
我有一个长字符串s,它表示由逗号和破折号分隔的一系列数字(见下文)。当几个数字互相跟随时,两个极端数字被写成并用一个破折号分开。例如,系列4,5,6,7被编写为4-7。我的目标是扩展这个字符串,使所有数字都由comas分隔(4-7应该变成4,5,6,7)。
我做了什么,
下面是字符串的一个示例
s="4092-4093,4095-4097,4104,4107,4111,4125-4127"我想首先用4-7 (使用sed反向引用)替换{4..7}类型的模式。
a="$(echo $s | sed 's/\([0-9]*\)-\([0-9]*\)/{\1..\2}/g')",然后计算字符串以展开大括号。
b="$(eval echo $a)"但是,当我运行最后一个命令时,展开是“以阶乘方式”完成的(导致RAM使用量激增)。
问题
如何将4-7类型的模式替换为字符串中的4,5,6,7?
版本
我在Mac OS X 10.11.3上使用Terminal 2.6.1 (361.1)
发布于 2016-08-15 23:13:46
一个使用GNU awk的答案,它应该在大量输入时表现得更好:
#!/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中(为了更好地使用少量数据):
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发布于 2016-08-15 23:14:25
s="4092-4093,4095-4097,4104,4107,4111,4125-4127"
a="$(echo $s | sed 's/\([0-9]*\)-\([0-9]*\)/{\1..\2}/g' | tr "," " ")"
b=""
for i in ${a[@]}
do
add="$(eval echo $i)"
b="${b} ${add}"
done
echo $b发布于 2016-08-15 23:42:35
Perl拯救了:
echo 4092-4093,4095-4097,4104,4107,4111,4125-4127 \
| perl -lane 's/-/../g;print join ",", eval'在Perl中,范围是用..运算符编写的,而不是用破折号编写的。在上面运行评估将字符串扩展到实际列表。
https://stackoverflow.com/questions/38964169
复制相似问题