bash - pulling content from array via index - arrays

I am having trouble with a script that prints out the index and items of the array and then allows the user to input an index that will print out that specific item of the array.
array=(abc def ghi)
i=0
while [ $i -lt ${#array[*]} ]; do
echo "[$i] ${array[$i]}"
i=$(($i+1));
done
echo -e "select an index: "; read answer
#this is the part that is troubling me
for index in ${!array[*]}; do
if [[ $answer == $index ]]; then
echo ${array[$index]}
break
else
echo "invalid"
break
fi
done
so if the user enters 0, it should print abc. 1 would be def etc. It currently only works for index 0.

Couple of problems in there that I can find:
you need a space right after $item to separate from the ]
$item should probably be $index
most importantly, remove the break after the "echo invalid" which is the reason the loop exits right after testing against '0' and doesn't check for the next array indexes. Using a flag then you should control if the answer matched any of the valid indexes, otherwise print the "invalid" message. I used a very explicit string test there for clarity.
A running code should look like:
array=(abc def ghi)
i=0
while [ $i -lt ${#array[*]} ]; do
echo "[$i] ${array[$i]}"
i=$(($i+1));
done
echo -e "select an index: "; read answer
for index in ${!array[*]}; do
found="FALSE"
if [[ "$answer" == "$index" ]]; then
found="TRUE"
echo "${array[$index]}"
break
fi
done
if [ "$found" == "FALSE" ]; then
echo "Invalid input $answer"
fi

Related

How to search if a value is present in array like variable using Bash script?

I have the below text, as the output of some command myscript.sh;
[
"string-1",
"string-2"
]
I have stored the output to some variable like below:
myarray=$(myscript.sh)
Now, I would like to echo value not present if the string string-3 is not present in the array, something like the code below;
value="string-3"
if [[ ! " ${myarray[*]} " =~ " ${value} " ]]; then
echo "value not present"
fi
This code will output value not present even if the value is present. What can be done to fix this issue?
The myarray variable is a string, and regular expressions can be used to determine whether it contains the specified substring.
myarray=([
"string-1",
"string-2"
])
value="string-3"
if [[ ! "$myarray" =~ .*"$value".* ]]; then
echo "value not present"
fi
Is the input a JSON array? If so, you should use a JSON-aware tool, like jq, to deal with it. Something like this:
if jq -e --arg value "$value" 'any(. == $value)' <<<"$myarray" >/dev/null; then
Explanation: --arg value "$value" copies the shell variable value into a jq variable with the same name. <<<"$myarray" passes the value of that variable as input (since it's not a bash array, the [*] is irrelevant). The filter any(. == $value) returns true if any array elements match $value, false otherwise. The -e option tells jq to use that result as its exit status, and >/dev/null discards the textual output. Since if uses the exit status of the command as its condition, that should be all you need.
Rewrite it like this:
if [[ ! $myarray =~ $value ]]; then
echo "value not present"
fi
Or like that:
[[ $myarray =~ $value ]] || echo "value not present"
Those "" spoiling everything.

storing user values in an array then comparing these variables using bash

while read line
do
if [ $line -ge $zero ]
then
a+=($line) ##here I am attempting to store the values in an array
else
for i in ${a[#]}
do
echo $(a[$i]) ## here I am trying to print them
done
fi
what is going wrong? it is giving this error:
a[1]: command not found
a[2]: command not found
a[3]: command not found
done
From the begining
if [ $line -ge $zero ]
what data type should be in $line?
-ge used in numeric comparison. If $line is a string than use = or if you just wnt to check that it's not empty use this syntax if [[ "$line" ]]
Next.
a+=($line)
Again if $line is a string then you should wrap in "" like this a+=("$line")
coz line can contain spaces.
For loop.
for i in ${a[#]}
do
echo $(a[$i]) ## here I am trying to print them
You'r messing with syntax here for i in ${a[#]} will iterate over arrays values, not indexes. And again if values are strings use "" like this for i in "${a[#]}"
So this echo $(a[$i]) won't work by 2 reasons. First you should use {} here, like this echo ${a[$i]}, second $i is not index, but it's may actualy work if it's a digit but in a wrong way. So here you need just echo $i coz $i is alredy a value from a array. Or rewrite foor loop.
for i in ${!a[#]}
do
echo ${a[$i]} ## here I am trying to print them
done
And last but not least, there is no done at the end of this script or it's just a part? So in the and it should look like this.
while read line; do
if [[ $line ]]; then
a+=( "$line" ) ##here I am attempting to store the values in an array
else
for i in ${!a[#]}; do
echo ${a[$i]} ## here I am trying to print them
done
fi
done < data.txt
echo ${a[#]} # print rusult

How read dynamic arrays in bash <4.3 version

I have a problem reading the contents of dynamic arrays.
Here I create dynamic arrays:
j=0
tab="project_"
for i in "${unique[#]}"
do
echo -n $i
eval ${tab}${i}=\(\)
#eval $tab$i[0]="test"
while read text
do
if [ "${i}" == "${text}" ]; then
echo " - OK "
eval ${tab}${i}=\(\)
k=0
z=0
x=0
for k in "${array[#]}"
do
z=`expr ${z} + 1`
if [[ "${i}" == "${k}" ]]; then
eval $tab$i[x]+=${array[`expr $z + 1`]}
x=`expr ${x} + 1`
fi
done
fi
done < "$allProjects"
for name in "${tab}${i[#]}"
do
echo "$name"
for n in "${name[#]}"
do
#eval echo "\${${tab}${i}[#]}" #this line will work, but I do not want to use eval
echo ${n} # <-- Here I would like to read it with
# the echo command, but it does not work
# I get the name of a dynamic array, but
# I want to get its contents.
done
done
#eval echo \${#${tab}${i}[#]}
#eval echo "\${${tab}${i}[#]}"
done
Maybe it's confusing because it's a snippet of code.
The premise is to create dynaic arrays based on values from another array and add the word project_ to the beginning.
Later on to these dynamically created arrays enter values from yet another array.

Delete element from array when a condition match in shell script

I am iterating through the array in shell script and when condition matches i.e. if found 'b' want to delete that element from the array. I am not using the index position to iterate through. My array has values (a b c)
My code is
for h in $Arr
do
echo -e "Value of current element $h.\n"
if [ $h == "b" ]
then
echo -e "Delete it\n"
else
echo -e "Stay here\n"
fi
done
How can I delete 'b' when condition matches so that when I print my array it should print (a c) ??
You could build a temp array Brr with the accepted values, then assign Arrwith its value?
Arr=" a b c"
Brr=""
for h in $Arr
do
echo -e "Value of current element $h.\n"
if [ $h == "b" ]
then
echo -e "Delete it\n"
#do not add it to Brr
else
echo -e "Stay here\n"
# add it to Brr the temp array
Brr="${Brr} $h"
fi
done
Arr="${Brr}"
echo $Arr

Add value to array using Bash script

I have written the following script ,
#!/bin/bash
My_File=Image.csv
Value=YES
cat "$My_File" | while IFS=, read first last
do
echo "first='$first' last='$last'"
if [ "$last" == "$Value" ];
then
echo Match_Found
echo $first
array+=("$first")
echo $first is Added
fi
done
echo (${#array[#]})
It dosenot add any value to the array , Could someone point out to the issue .
The Input is as follow ,
FA_2015-01_666,NO
FA_2015-01_777,YES
FA_2015-01_888,NO
FA_2015-01_999,YES
FA_2015-01_555,YES
Redirect the file in, don't pipe from cat or the loop is run in a subshell and everything in it is lost when it ends.
#!/bin/bash
My_File="Image.csv"
Value=YES
while IFS=, read first last
do
if [ "$last" == "$Value" ];
then
echo Match_Found
echo $first
array+=("$first")
echo $first is Added
fi
done < "$My_File"
echo "${#array[#]}"
I haven't done some bash coding in some time, but it should be like this (The way i do it):
#our table to insert an item to
table=( )
tableLength=${#table[#]}
#inserting items
table[$tableLength]="foo"
#you have to refresh this variable everytime
tableLength=${#table[#]}
table[$tableLength]="bar"
#or you can do this without refreshing the length variable
table[${#table[#]}]="foobar"
I recommend you use:
table=()
table[${#table[#]}]="item!"
using # as the length, and table[#] to display all items, so it gets the length of the array and sets an item to the length of an array or table

Resources