echo "Please enter a number/string: " #4539319503436467
read string
set -x
array=()
for (( x=${#string}-1; x >= 0; x-- ))
do
echo "x is:$x"
array+={string:$x:1} # or array+=( $string:$x:1 )
done
declare -p array
The output I’m getting:
Please enter a number/string:
4539319503436467
+ array=()
+ (( x=16-1 ))
+ (( x >= 0 ))
+ echo 'x is:15'
x is:15
+ array+='{string:15:1}'
+ (( x-- ))
+ (( x >= 0 ))
+ echo 'x is:14'
x is:14
+ array+='{string:14:1}'
+ (( x-- ))
+ (( x >= 0 ))
<----------SNIP------------->
declare -p array
declare -a array=([0]="{string:15:1}{string:14:1}{string:13:1}
{string:12:1}{string:11:1}{string:10:1}{string:9:1}{string:8:1}
{string:7:1}{string:6:1}{string:5:1}{string:4:1}{string:3:1}
{string:2:1}{string:1:1}{string:0:1}")
or I get the full input string: {4539319503436467:15:1}
This is a tricky bit of bash syntax. array is defined to be an array.
To append to it, you need to still use parentheses
array+=( "a new element" )
Where you’re getting hung up is with the variable expansion syntax. To extract a substring starting at offset and extending for length characters, you must use this syntax, with the dollar and the braces.
${varname:offset:length}
Put that together:
array+=( "${string:$x:1}" )
The double quotes are needed here.
Bash arrays are odd. If you start to treat the variable as a plain “scalar” variable, you intract with the element at index 0
This exercise calls for doubling every 2nd digit of the input from the top.
So in this case using 4539319503436467 as the input, it would be 6, 6, 4, 0, 9, 3, 3, 4
I can’t get my head around how to do this. I’m thinking something like this:
echo "Please enter a number/string: " #input-4539319503436467
read string
for (( x=${#string}; x >= 0; x-- ))
do
if [[ x is in the 2nd position ]]
then
$temp=$x
$temp*2
fi
Ah, I see. That’s clever.
I believe the logic of the structure works, but the problem I’m running into now is there are 3 different assignments to the array, and each one doesn’t append/assign individually to each of the 16 elements of the index. The assignments either overwrite an existing element, or there are multiple assignments to the same element. I’m sure it has something to do with the syntax.
#!/bin/bash
echo "Please enter a number/string: " #4539319503436467
read -r string
set -x
array=()
temp=0
for (( x=${#string}-1; x >= 0; x-- ))
do
math=$((x % 2)) #if number is every 2nd position of index...
if [[ $math -eq 0 ]] #and is an even index number
then
temp=$((${string:$x:1}*2)) #double *value*, and assign it to $temp
if [[ $temp -gt 9 ]] #if $temp is greater than 9
then
array=$(( temp - 9 )) #subtract 9 and assign to array
else
array=$( "$temp" )
fi
else
array+=( "${string:$x:1}" ) # odd index numbers
declare -p array
fi
done
declare -p array
I’m trying to get each assignment to the array in it’s own index. I don’t think the direction matters.
I added $x from the for loop, to each array assignment. That way, it did the assignment for each index it encountered along the way. I couldn’t get it to work the other way. I was getting multiple values in the same element, values overwritten, etc.
You could try describing what you’re trying to do in English/pseudocode and we can show how that’s done.
It’s really hard when someone says, “Here is code that doesn’t accomplish X. Is this on the right track to accomplish X?” We don’t know what X and we can’t derive X from the code which doesn’t do X. That makes it hard to tell if the code (which doesn’t do X) is close to doing X (whatever X might be).
Which you can see in the code below.
This was not working, so just wondering if I was missing something.
#!/bin/bash
echo "Please enter a number/string: " #4539319503436467
read -r string
set -x
array=()
temp=0
for (( x=${#string}-1; x >= 0; x-- ))
do
math=$((x % 2)) #if number is every 2nd position of index...
if [[ $math -eq 0 ]] #and is an even index number
then
temp=$((${string:$x:1}*2)) #double *value*, and assign it to $temp
if [[ $temp -gt 9 ]] #if $temp is greater than 9
then
array=$(( temp - 9 )) #subtract 9 and assign to array
else
array=$( "$temp" )
fi
else
array+=( "${string:$x:1}" ) # odd index numbers
declare -p array
fi
done
declare -p array
One of these assigns a value to the same position/index/key $x in the array three times while the other appends a new element three times.
Saying that this is the same code from before, reiterating that this code doesn’t work and showing the broader file all fail to explain what you are hoping to accomplish with this code. Intent should be expressed in regular English, not by providing code.
I’m trying to check if the user input contains anything that is not a digit, or is 1 character or less in length, and produce an error if any of these conditions are true.
echo "Please enter a number/string: "
read -r string
for (( i=0; i <= ${#string}; i++ ))
do
if [[ ${string:$i:1} =~ [^[:digit:]] || ${string:$i:1} | wc -m -le 1 ]]
then
echo "Sorry contains a non-digit, or input is 1 character or less. Try again."
else...
fi
done
In the if statement, if I take out the 2nd condition, the regex seems to work on it’s own. If I add the ${string:$i:1} | wc -m -le 1 back, it stops working.
In that 2nd condition, I’m trying to pipe the current character of string into wc, then test if it’s less than or equal to 1.
If you’re not sure it works, then you should double check where you came up with it ;) Does the code otherwise work with that part removed? Then that would suggest that part isn’t working. This is how you narrow down the issue to isolate the problem.
I’ve tried to do the same test outside of [[, and isolating it. It still doesn’t work.
temp2=0
for (( i=0; i <= ${#string}; i++ ))
do
${string:$i:1} | $temp2=$wc -m
echo "$temp2"
if [[ $temp2 -le 1 ]]
then
echo "Sorry, input is 1 character or less. Try again."
fi
done
I get set -x output like this:
Please enter a number/string:
45
+ (( i=0 ))
+ (( i <= 2 ))
+ 4
./luhn.sh: line 29: 4: command not found
+ 0= -m
./luhn.sh: line 29: 0=: command not found
+ echo 0
0
+ [[ 0 -le 1 ]]
Looks like it’s not assigning the value of the input to temp2, which is just 0.
That’s neither how you’d pipe a string to a command nor how you’d assign the output of a command to a variable. You might want to read up on basic shell syntax rather than making up syntax, hoping it will work and asking why it doesn’t work The Wooledge Guide is pretty solid. If you work your way through that, the Luhn exercise should be pretty easy.