Values rotation in array with bash


Login or Register for Dates, Times and to Reply

 
Thread Tools Search this Thread
# 1  
Values rotation in array with bash

Hello Smilie

I created a little script that allow to make a rotation of values in an array. The goal was to shift the values to the right and that the last value of the array became the first value in order to create a rotation.

The purpose of the exercice was to do it without using a temporary array but to create a temporary variable in which I can put one of the values of the array then shifted all values to the right and then, put the temporary variable in the array.

Here my script :

Code:
#!/bin/bash

clear
declare -a array

read -rp " How many cases ? " box
read -rp " shift : " n
  
array=( $(seq 1 "$box"))
tmp=${array[-2]}

for((i=$tmp;i>0;i--))
do
 	array[$i]=${array[$i -1]}
done

array[0]=$tmp

for((i=0; i<$box;i++))
do
	array[$i]
done

echo " Original array : " ${array[*]}
echo " Temporary variable : " $tmp 
echo " Array shifted : ${array[*]}"

But with 2 places to shift, the result is :

Code:
Original array : 9 1 2 3 4 5 6 7 8 9
Temporary variable : 2
Array shifted : 9 1 2 3 4 5 6 7 8 9

Or I want this result :
Code:
Original array : 1 2 3 4 5 6  7 8 9 10 
Temporary variable : 2
Array shifted : 9 10 1 2 3 4 5 6 7 8

I can't set up this little script... Can you help me to solve it ?

BTS SIO/SISR - Gaston Berger
# 2  
You seem to have some logical errors in your script:
- mixing up array indices with array values (tmp being assigned a value but then used for an index).

- using a constant (2) when the shift span (n) is given.
- outputting the modified array twice instead of comparing the two before and after


How about
Code:
$ array=( $(seq 1 "$box"))
$ echo " Original array : " ${array[*]}
 Original array :  1 2 3 4 5 6 7 8 9 10
$ echo " shift:" $n
 shift: 4
$ array=( $(for ((i=n; i; i--)); do echo -n  ${array[-i]}" "; unset array[-i];  done; echo ${array[@]}) )
$ echo " array shifted : " ${array[*]}
 array shifted :  7 8 9 10 1 2 3 4 5 6

These 2 Users Gave Thanks to RudiC For This Post:
# 3  
Comment on the previous solution: it allows echo ${array[-i]} because the =( ) splits on IFS i.e. space and newline.

If there is a cyclic shift, the % operator (modulo) is nice!
The following allows a very big (and even negative) shift:

Code:
...
# print array[ ] right-shifted by n
print_array_shifted(){
  local len=${#array[@]}
  local start=$((10*len-n))
  local end=$((start+len))
  local i
  for ((i=start; i<end; i++))
  do
    echo "${array[i%len]}"
  done
}

echo " Original array : ${array[*]}"
array=( $(print_array_shifted) )
echo " Array shifted : ${array[*]}"


Last edited by MadeInGermany; 05-27-2019 at 02:24 PM.. Reason: 10*len because bash-3 does not allow negative index
These 2 Users Gave Thanks to MadeInGermany For This Post:
# 4  
Quote:
Originally Posted by RudiC
You seem to have some logical errors in your script:
- mixing up array indices with array values (tmp being assigned a value but then used for an index).

- using a constant (2) when the shift span (n) is given.
- outputting the modified array twice instead of comparing the two before and after


How about
Code:
$ array=( $(seq 1 "$box"))
$ echo " Original array : " ${array[*]}
 Original array :  1 2 3 4 5 6 7 8 9 10
$ echo " shift:" $n
 shift: 4
$ array=( $(for ((i=n; i; i--)); do echo -n  ${array[-i]}" "; unset array[-i];  done; echo ${array[@]}) )
$ echo " array shifted : " ${array[*]}
 array shifted :  7 8 9 10 1 2 3 4 5 6

Quote:
Originally Posted by MadeInGermany
Comment on the previous solution: it allows echo ${array[-i]} because the =( ) splits on IFS i.e. space and newline.

If there is a cyclic shift, the % operator (modulo) is nice!
The following allows a very big (and even negative) shift:

Code:
...
# print array[ ] right-shifted by n
print_array_shifted(){
  local len=${#array[@]}
  local start=$((len-n))
  local end=$((start+len))
  local i
  for ((i=start; i<end; i++))
  do
    echo "${array[i%len]}"
  done
}

echo " Original array : ${array[*]}"
array=( $(print_array_shifted) )
echo " Array shifted : ${array[*]}"

Hello ! Smilie

Thank you for your help !!

For me, the only problem was this line :

Code:
unset array[-i]

So I had to replace this line by :

Code:
  Unset array[$(( ${#array[*]}-1))]

Now it works perfectly ! Thank you very much ! Smilie
# 5  
Quote:
Originally Posted by Nexy
Hello ! Smilie

Thank you for your help !!

For me, the only problem was this line :

Code:
unset array[-i]

So I had to replace this line by :

Code:
  Unset array[$(( ${#array[*]}-1))]

Now it works perfectly ! Thank you very much ! Smilie
Hi, you should be able to shorten this to:
Code:
unset array[${#array[@]}-1]

# 6  
Maybe this will help?
Code:
arr=(${arr[@]: -2} ${arr[@]:0:$((${#arr[@]}-2))})
echo ${arr[@]}

These 2 Users Gave Thanks to nezabudka For This Post:
# 7  
Very nice! Will also work with a shift variable.


And, you don't need the "Arithmetic Expansion" $((...)) within the array expansion:


Code:
echo ${arr[@]: -shift} ${arr[@]:0:${#arr[@]}-shift}


Last edited by RudiC; 05-26-2019 at 07:39 AM..
This User Gave Thanks to RudiC For This Post:
Login or Register for Dates, Times and to Reply

Previous Thread | Next Thread
Thread Tools Search this Thread
Search this Thread:
Advanced Search

Test Your Knowledge in Computers #720
Difficulty: Medium
Alan Minsky was an adviser on Stanley Kubrick's movie 2001: A Space Odyssey.
True or False?

9 More Discussions You Might Find Interesting

1. Shell Programming and Scripting

Values rotation in array with bash

Hello :) I created a little script that allow to make a rotation of values in an array. The goal was to shift the values to the right and that the last value of the array became the first value in order to create a rotation. The purpose of the exercice was to do it without using a temporary... (3 Replies)
Discussion started by: Nexy
3 Replies

2. Shell Programming and Scripting

Bash Array connectin to another Array

Hello, i have a script that i need account_number to match a name. for exsample : ACCOUNT_ID=(IatHG8DC7mZbdymSoOr11w KbnlG2j-KRQ0-1_Xk356s8) and i run a loop curl requst with this the issue is that i want to know on which account were talking about so bash will know this : ... (4 Replies)
Discussion started by: batchenr
4 Replies

3. Shell Programming and Scripting

Bash arrays: rebin/interpolate smaller array to large array

hello, i need a bit of help on how to do this effectively in bash without a lot of extra looping or massive switch/case i have a long array of M elements and a short array of N elements, so M > N always. M is not a multiple of N. for case 1, I want to stretch N to fit M arrayHuge H = (... (2 Replies)
Discussion started by: f77hack
2 Replies

4. Shell Programming and Scripting

How to find the X highest values in a list depending on the values of another list with bash/awk?

Hi everyone, This is an exemple of inpout.txt file (a "," delimited text file which can be open as csv file): ID, Code, Value, Store SP|01, AABBCDE, 15, 3 SP|01, AABBCDE, 14, 2 SP|01, AABBCDF, 13, 2 SP|01, AABBCDE, 16, 3 SP|02, AABBCED, 15, 2 SP|01, AABBCDF, 12, 3 SP|01, AABBCDD,... (1 Reply)
Discussion started by: jeremy589
1 Replies

5. Shell Programming and Scripting

Bash 3.2 - Array / Regex - IF 3rd member in array ends in 5 digits then do somthing...

Trying to do some control flow parsing based on the index postion of an array member. Here is the pseudo code I am trying to write in (preferably in pure bash) where possible. I am thinking regex with do the trick, but need a little help. pesudo code if == ENDSINFIVEINTS ]]; then do... (4 Replies)
Discussion started by: briandanielz
4 Replies

6. Red Hat

Values in array are not able to be used one by one

hey,i stored the value of an sql query in an array and then tried to use that value in while loop. actually my array will have two or more values, then according to the values i have to display result. #!/bin/bash -xv val_1=$( sqlplus -s rte/rted1@rel75d1 << EOF set heading off select... (1 Reply)
Discussion started by: ramsavi
1 Replies

7. UNIX for Dummies Questions & Answers

Passing values from file into array in Bash

Hi, I'm trying to write a bash script that takes a file and passes each line from the file into an array with elements separated by column. For example: Sample file "file1.txt": 1 name1 a first 2 name2 b second 3 name3 c third and have arrays such as: line1 = ( "1" "name1" "a"... (3 Replies)
Discussion started by: ShiGua
3 Replies

8. Shell Programming and Scripting

Greping array values in Bash like Perl

Hi, Is there an easy way to simulate following Perl code in Bash. if ( grep {$my_value eq $_} @ARGV ){ print "Do Something\n"; } else { die "Invalid value"; } (0 Replies)
Discussion started by: paragkalra
0 Replies

9. Shell Programming and Scripting

PHP: Search Multi-Dimensional(nested) array and export values of currenly worked on array.

Hi All, I'm writing a nagios check that will see if our ldap servers are in sync... I got the status data into a nested array, I would like to search key of each array and if "OK" is NOT present, echo other key=>values in the current array to a variable so...eg...let take the single array... (1 Reply)
Discussion started by: zeekblack
1 Replies

Featured Tech Videos