Reputation: 12272
Lets say I have a string of 4 numbers separated by space
1 4 16 28
# stored in $ids
So, to get the 4 number separately in four variables I was using
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")
But the problem is, if the string has less then 4 numbers, the previous numbers are repeated.
For example, if the string was
1
then what we will get is
id1=1
id2=1
id3=1
id4=1
What I want is that, if there are less numbers, then the extra variables should have the value 0
.
Is there a way to do that?
Note : I can only use sed
Upvotes: 1
Views: 110
Reputation: 532428
You don't need sed
. This will work in any POSIX-compatible shell:
read -r id1 id2 id3 id4 rest <<EOF
$ids 0 0 0 0
EOF
This will work for any number of values in ids
. The line in the here document will contain at least 4 values, regardless of the value of ids
, and any extra fields will be assigned to rest
and can be ignored.
Upvotes: 0
Reputation: 37464
Try this regex instead, it returns ""
if there is nothing to return:
$ 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
$
Upvotes: 1
Reputation: 74705
If you can use awk, you could try something like this:
$ 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
The function tests whether the field contains one or more digits, replacing with 0
if it doesn't.
The best way to get the output into separate variables depends on what you plan on doing with them later and your shell version.
Using process substitution, you can do this:
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) }')
Less efficient but perhaps easier to understand would be to simplify the script and run it 4 times:
id1=$(echo "$str" | awk -v col=1 '{ print $col ~ /^[0-9]+$/ ? $col : 0 }')
Upvotes: 1