正则表达式的一串数字

时间:2016-10-05 09:48:11

标签: regex bash sed

假设我有一串由空格分隔的4个数字

1 4 16 28
# stored in $ids

所以,为了在我使用的四个变量中分别得到4号

id1=$(echo $ids | sed -r "s/([0-9]+ ){0}([0-9]+) ?.*/\2/g")
id2=$(echo $ids | sed -r "s/([0-9]+ ){1}([0-9]+) ?.*/\2/g")
id3=$(echo $ids | sed -r "s/([0-9]+ ){2}([0-9]+) ?.*/\2/g")
id4=$(echo $ids | sed -r "s/([0-9]+ ){3}([0-9]+) ?.*/\2/g")

但问题是,如果字符串少于4个数字,则重复之前的数字。

例如,如果字符串是

1

那么我们将得到的是

id1=1
id2=1
id3=1
id4=1

我想要的是,如果数字较少,则额外变量的值应为0

有办法吗?

注意:我只能使用sed

3 个答案:

答案 0 :(得分:1)

如果你可以使用awk,你可以尝试这样的事情:

$times = $_.Group | Select-Object -Expand Time
for ($i=1; $i -le $timeCols; $i++) {
  $props["Time#$i"] = $times[$i]
}

该函数测试该字段是否包含一个或多个数字,如果没有,则替换为$ awk 'function m(a) { return a ~ /^[0-9]+$/ ? a : 0 } { print m($1), m($2), m($3), m($4) }' 1 4 16 281 # input 1 4 16 281 1 # input 1 0 0 0

将输出转换为单独变量的最佳方法取决于您计划稍后使用它们以及shell版本。

使用流程替换,您可以这样做:

0

效率较低但可能更容易理解的是简化脚本并运行4次:

str='1 4 16 281'
read -r id1 id2 id3 id4 < <(echo "$str" | awk '
  function m(a) { return a ~ /^[0-9]+$/ ? a : 0 } 
    { print m($1), m($2), m($3), m($4) }')

答案 1 :(得分:1)

尝试使用此正则表达式,如果无法返回,则返回""

$ echo 1 2 3 4 5 6|sed -r "s/^([0-9]+ *){0,3}//g;s/([0-9]+).*/\1/g;s/^$/0/g"
4
#                 change this latter value ^ 

$ echo 1 2 3|sed -r "s/^([0-9]+ *){0,3}//g;s/([0-9]+).*/\1/g;s/^$/0/g"
0
$

答案 2 :(得分:0)

您不需要sed。这适用于任何与POSIX兼容的shell:

read -r id1 id2 id3 id4 rest <<EOF
$ids 0 0 0 0
EOF

这适用于ids中的任意数量的值。无论ids的值如何,此处文档中的行都将包含至少4个值,并且任何额外字段都将分配给rest,并且可以忽略。