bash + what the opposite operation of the unset command + add arr member - arrays

Deleting value from array in bash is very simple as the following:
remove the first value from array:
arr=(1 2 3 4 5 6)
unset arr[0]
echo ${arr[*]}
2 3 4 5 6
remove the second value from the last array:
unset arr[1]
echo ${arr[*]}
3 4 5 6
But how to add new value to array in bash ? , is it possible?
for example - add the value 10 after the first arr member
3 10 4 5 6

You can do:
arr=(1 2 3 4 5 6)
unset arr[0]
unset arr[1]
arr[1]="${arr[2]}"
arr[2]=10
echo "${arr[#]}"
3 10 4 5 6

To add an item 5 to table arr
arr=(${arr[*]} 5)
Ordering in bash is made throught sort command... Otherwise I advise you to use an other language.

Related

'if' in array w/ Shell Script

I have an array with different values, and if the value is 3 (integer) this value will be exchanged for 999 (integer). But I have a syntax problem in the 'if' block of the array.
The correct return would be: 1 999 5 7 9 999
vetor=(1 3 5 7 9 3)
for i in ${vetor[*]}
do
if [[ ${vetor[i]} = 3 ]]; then
${vetor[i]} = 999
fi
echo $i
done
This produces the correct output in Bash:
vetor=(1 3 5 7 9 3);
for i in ${!vetor[*]};
do
if [[ ${vetor[i]} -eq 3 ]]; then
vetor[i]=999;
fi;
echo ${vetor[i]};
done
I added ! in the for loop expression to get the indices of vetor instead of the values, and I removed the ${} around the assignment in the if condition (this was giving "if 3 is not a typo" warnings). Also changed the echo to get the value at vetor[i] instead of printing the index.

Modify IFS in bash while building and array

I'm trying to build an array from 4 different arrays in bash with a custom IFS, can you lend me a hand please.
#!/bin/bash
arr1=(1 2 3 4)
arr2=(1 2 3 4)
arr3=(1 2 3 4)
arr4=(1 2 3 4)
arr5=()
oldIFS=$IFS
IFS=\;
for i in ${!arr1[#]}; do
arr5+=($(echo ${arr1[i]} ${arr2[i]} ${arr3[i]} ${arr4[i]}))
done
IFS=$oldIFS
echo ${arr5[#]}
i what the output to be:
1 1 1 1;2 2 2 2;3 3 3 3;4 4 4 4 4 4
But it doesn't work the output is with normal ' '.
1 1 1 1 2 2 2 2 3 3 3 3 4 4 4 4 4 4
Any ideeas?
I tried IFS in different places:
1) In the for loop
2) Before arr5()
I tested it in the for loop and after IFS does change to ";" but it doesn't take effect in the array creation.
IFS is used during the expansion of ${arr5[*]}, not while creating arr5.
arr1=(1 2 3 4)
arr2=(1 2 3 4)
arr3=(1 2 3 4)
arr4=(1 2 3 4)
arr5=()
for i in ${!arr1[#]}; do
arr5+=("${arr1[i]}" "${arr2[i]}" "${arr3[i]}" "${arr4[i]}")
done
(IFS=";"; echo "${arr5[*]}")
Where possible, it's simpler to just change IFS in a subshell rather than try to save and restore its value manually. (Your attempt fails in the rare but possible case that IFS was unset to begin with.)
That said, if you just want the ;-delimited string and arr5 was a way to get there, just build the string directly:
for i in ${!arr1[#]}; do
s+="${arr1[i]} ${arr2[i]} ${arr3[i]} ${arr4[i]};"
done
s=${s%;} # Remove the last extraneous semicolon

How to identify the position of a sequence of elements in an array in bash

I'm learning bash and I'm trying identify a sequence elements (patch or subarray) position into a array.
For example:
array=(9 5 8 3 2 7 5 9 0 1 1 5 4 3 8 9 6 2 6 5 7 9 8);
patch=(0 1 1 5)
I would like to obtain a output equals to 8 (start position of my patch in relation to array) or 11 (final position).
bash doesn't really have any built-in facility to do this; you need to walk the array yourself:
for ((i=0; i<${#array[#]}; i++)); do
for ((j=0; j<${#patch[#]}; j++)); do
# Make sure the corresponding elements
# match, or give up. RHS is quoted to ensure
# actual string equality, rather than just pattern matching
[[ ${array[i+j] == "${patch[j]}" ]] || break
done
if [[ $j == ${#patch[#] ]]; then
# All the comparisons succeeded!
start=$i
finish=$((i+j-1))
break
fi
done

Linux Bashrc Nexted For Loops

Below is my code, I have two arrays...array and array2.
#!/bin/bash
array = (1 3 5 7 9)
array2 = (2 4 6 8 A)
for i in "${array[#]}"
do
echo $i
for i in "${array2[#]}"
do
echo $i
done
done
I want to have the following output echoed out onto my console when I run my script:
1
2
3
4
5
6
7
8
9
A
But instead I get the following:
1
2
4
6
8
A
3
2
4
6
8
A
5
2
4
6
8
A
7
2
4
6
8
A
9
2
4
6
8
A
I'm really trying to accomplish the following through nested loops like in C/C++:
char array[5] = {1, 3, 5, 7, 9};
char array2[5] = {2, 4, 6, 8, A};
for (int i=0; i<5; i++){
std::cout << array[i] << std::endl;
std::cout << array2[i] << std::endl;
}
But how can I use the same iterator var i to control two different arrays?
Loop over the indices instead of the elements:
#!/bin/bash
array=(1 3 5 7 9)
array2=(2 4 6 8 A)
for i in "${!array[#]}"
do
echo "${array[i]}"
echo "${array2[i]}"
done
The more or less exact transcription of the c++ code would be
for i in {0..5}
do
echo ${array[$i]}
echo ${array2[$i]}
done
To add another algorithm, you can repeatedly print the first element of each array and pop them until the first is empty:
array=(1 3 5 7 9)
array2=(2 4 6 8 A)
while [ -n "$array" ]
do
echo ${array[0]}
echo ${array2[0]}
array=("${array[#]:1}")
array2=("${array2[#]:1}")
done
edit: This does destroy the arrays as you go, so only use it if you don't care about the arrays existing after the loop.

bad substitution shell- trying to use variable as name of array

#!/bin/bash
array=( 2 4 5 8 15 )
a_2=( 2 4 8 10 )
a_4=( 2 4 8 10 )
a_5=( 10 12 )
a_8=( 8 12 )
a_15=( 2 4 )
numberOfTests=5
while [ $i -lt ${#array[#]} ]; do
j=0
currentArray =${array[$i]}
*while [ $j -lt ${#a_$currentArray [#]} ]; do #### this line i get ->>>> bad substitution*
./test1.sh "${array[$i]}" -c "${a_"$currentArray "[$j]}" &
let j=j+1
done
let i=i+1
done
so Im trying this code, loop over an array(called array), The array should point out
the array number we are now looping(a_X). And every time to point out the current place and value.
can anybody help me how im using the $currentArray to work properly so I can know the length of the array and the value?
I get in the line I marked an error.
Thank you guys!
The simplest solution is to store the full names of the arrays, not just the numerical suffix, in array. Then you can use indirect parameter expansion while iterating directly over the values, not the indices, of the arrays.
# Omitting numberOfTests has it does not seem to be used
array=(a_2 a_4 a_5 a_8 a_15)
a_2=( 2 4 8 10 )
a_4=( 2 4 8 10 )
a_5=( 10 12 )
a_8=( 8 12 )
a_15=( 2 4 )
for arr in "${array[#]}"; do
currentArray=$arr[#]
for value in "${!currentArray}"; do
./test1.h "${arr#a_}" -c "$value" &
done
done

Resources