1

The following list represented the tokens between sdb and sd$MAX (while MAX range could be c-z)

For example:

MAX=z
list=$(eval echo sd{b..$MAX})
echo $list

strings are: ( example )

sdb sdc sdd sde sdf sdg sdh sdi sdj sdk sdl sdm sdn sdo sdp sdq sdr sds sdt sdu sdv sdw sdx sdy sdz

my question how to shift the list each loop to the next string

example:

for i in disk1 disk2 disk3 disk4 ..................
do
echo $i    <...syntax...>
done

expected output

disk1   sdb
disk2   sdc
disk3   sdd
disk4   sde
.
.
.
1
  • Are those disk names just numbers like that, or can they be arbitrary strings? i.e. why take them off a list if you can generate them by iterating over the number? Commented Jan 15, 2018 at 20:45

4 Answers 4

3

You could use indirection to loop over the array's indices rather than its values directly e.g.

Given

$ list=(sd{a..f})
$ echo "${list[@]}"
sda sdb sdc sdd sde sdf

then

$ for i in "${!list[@]}"; do printf '%s %s\n' "disk${i}" "${list[$i]}"; done
disk0 sda
disk1 sdb
disk2 sdc
disk3 sdd
disk4 sde
disk5 sdf

If you really want to do it your way, then you will need to extract a usable integer index from the elements of the strings that you're looping over e.g. by removing the leading string disk using parameter substitution:

for d in disk1 disk2 disk3 disk4; do printf '%s %s\n' "$d" "${list[${d##disk}]}"; done
disk1 sdb
disk2 sdc
disk3 sdd
disk4 sde
5
  • I not want to use the ${!list[@]} in the for loop Commented Jan 15, 2018 at 19:17
  • for loop is only for the disks not for the sdX strings Commented Jan 15, 2018 at 19:17
  • @yael <shrug> OK - please see update for an alternative Commented Jan 15, 2018 at 19:25
  • why not use - counter=0 ; list=(sd{a..f}) ; and in the loop --> echo "${list[counter++]}" Commented Jan 15, 2018 at 19:44
  • it much more simple Commented Jan 15, 2018 at 19:44
1

It is better to use array variables:

#!/bin/bash

MAX=d
eval list=\( $(echo sd\{b..$MAX\})\)
eval disks=\( $(echo disk\{1..${#list[@]}\})  \)

for((i=0;i<=${#list[@]};i++));do
    echo "${disks[i]} ${list[i]}"
done

On execution:

$ ./script
disk1 sdb
disk2 sdc
disk3 sdd

Adapt as required.

1

Bash has two simple and straightforward built-in features that together will solve your problem: set and shift.

set $list will assign each element of $list to one of bash's positional parameters.

shift renames all positional parameter $n+1 to $n, effectively deleting $1 and "shifting" all positional parameters forward.

So, in your example, your statement echo $i <...syntax...> would be echo $i " " $1; shift.

BTW, personally, I would use bash's printf instead of echo (See elsewhere for trouble echo can give you): printf "%s %s\n" $i $1; shift

0

You may build a counter for disk column to feet the list & replace strings for use as export

-bash-4.4$ MAX=z
-bash-4.4$ list=$(eval echo sd{b..$MAX})
-bash-4.4$ echo $list
sdb sdc sdd sde sdf sdg sdh sdi sdj sdk sdl sdm sdn sdo sdp sdq sdr sds sdt sdu sdv sdw sdx sdy sdz
-bash-4.4$  disk=1 ; for i in $(echo $list) ; do echo $i | sed 's/sd./disk'$disk'\t &/' ; disk=$(($disk +1)) ; done
disk1    sdb
disk2    sdc
disk3    sdd
disk4    sde
disk5    sdf
disk6    sdg
disk7    sdh
disk8    sdi
disk9    sdj
disk10   sdk
disk11   sdl
disk12   sdm
disk13   sdn
disk14   sdo
disk15   sdp
disk16   sdq
disk17   sdr
disk18   sds
disk19   sdt
disk20   sdu
disk21   sdv
disk22   sdw
disk23   sdx
disk24   sdy
disk25   sdz
-bash-4.4$ 

be careful here I use a define variable disk to count & a \t (tabulation) as separator; you may adapt to feet your needs if you prefer a space or something else.

if you wanna get this output in a file add a redirection of output & of course in a script you may want to use code as this (without ; )

disk=1 
for i in $(echo $list) 
do 
  echo $i | sed 's/sd./disk'$disk'\t &/' ; disk=$(($disk +1))
done > file

this is the easy way to understand it. A better method is to use the bash substitution instead of sed see bash method ${!list[@]} & either printf command or ${parameter/pattern/string} substituion advanced functions ...

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.