Putting strings into positioning array in loop

i need to add 2 string variables into a positioning array , repeatedly - in loop.

First string in $2, second to $3 then up to the desired count incrementing the "position".
Using set -- alone does not increment the count so I end up with 2 variables in the array.

How do I increment the positioning index ?

 echo " # add loop" 
 arrayTEST=( "$@" )
 for i in {0..16..2}
 do 
 set -- "CLI command" "CLI command description "   # assign variables to ar$
# next position in array ??

 done 
 echo "# number of elements in array " 
 echo "$#"       # number of elements in array
 echo " # content  of array" 
 echo "$@"       # contennt  of array 
 

The positional parameters are limited in the sense that it can only be filled in one go, either by passing them to a script of function or using the set command.
So you can only manipulate the this to set the positional parameters, for example:

set -- "" "String in position 2" "Another string in pos 3" 

The empty string as the first parameter put the other strings in position 2 and 3.
But then the number of elements is not accurate, because
echo "$#" will report 3

But why don't you use a regular array, available in bash or ksh? Then you can put strings in any position you like.

arr[2]="String in element 2" 
arr[3]="Another string in element 3"

In this case the the elements arr[0] and arr[1] remain unused

$ echo "${#arr[@]}"
2

Sorry, but this post does not answer / address my question.

I have no problem building the array manually, but I was just trying to use loop.

Actually I like to know if such operation is even possible since the limit of the positioning parameters in the array is not defined.

Does this do what you want?

for i in {0..16..2}
do 
   set -- "$@" "CLI command" "CLI command description "
done

Andrew

Maybe.

Here is the debug output as code is being processed.

It looks to me that each pass add next string and than debug prints the whole file.

But it builds multiple "strings"and it really does not matter how.

I did add the "index" so I can "see" the progress.

Thanks

+ set -- 'CLI command' 'CLI command description ' 'CLI command' 'CLI command description ' 'CLI command' 'CLI command description ' 'CLI command' 'CLI command description ' 'CLI command' 'CLI command description ' 'CLI command' 'CLI command description '
+ echo 'index  10'
index  10
+ for i in {0..16..2}
+ set -- 'CLI command' 'CLI command description ' 'CLI command' 'CLI command description ' 'CLI command' 'CLI command description ' 'CLI command' 'CLI command description ' 'CLI command' 'CLI command description ' 'CLI command' 'CLI command description ' 'CLI command' 'CLI command description '
+ echo 'index  12'
index  12
+ for i in {0..16..2}
+ set -- 'CLI command' 'CLI command description ' 'CLI command' 'CLI command description ' 'CLI command' 'CLI command description ' 'CLI command' 'CLI command description ' 'CLI command' 'CLI command description ' 'CLI command' 'CLI command description ' 'CLI command' 'CLI command description ' 'CLI command' 'CLI command description '
+ echo 'index  14'
index  14
+ for i in {0..16..2}
+ set -- 'CLI command' 'CLI command description ' 'CLI command' 'CLI command description ' 'CLI command' 'CLI command description ' 'CLI command' 'CLI command description ' 'CLI command' 'CLI command description ' 'CLI command' 'CLI command description ' 'CLI command' 'CLI command description ' 'CLI command' 'CLI command description ' 'CLI command' 'CLI command description '
+ echo 'index  16'
index  16
+ pause
+ read -p 'Press [Enter] key to continue...'
Press [Enter] key to continue...


------ Post updated at 10:26 AM ------

OK. the code does the job. Many thanks.

Minor problem - now I need to copy the positioning array to a file.

This simple verification code does reads the array in reverse.
It would make things easier if I could add the lines into the file starting with 1 and go up.

I suppose I can change the while[condition] and check for # for != 16 in this case.

Or can I start from $# = 1 and shift "up" ?

testLoopAddition(){
  55 for i in {0..16..2}
  56 do 
  57    set -- "$@" "CLI command" "CLI command description "
  58    echo "index  $i"     
  59 done
  62 echo "In reverse start with $# positional parameters"
  63 # while positional parameter not empty 
  64 while [ "$1" != "" ]; do
  65     echo "Parameter $# equals $1"
          copy $1 to file here 

  68     shift
  69 done

How do you intend to copy these to a file? Is it one per line to the same file? If so, you could look at the bash built-in printf :

printf "%s\n" $* > file

This will print your parameter list as a list of space-separated strings, one per line, until your list is exhausted. Try this noddy program:

#!/bin/bash

printf "%s\n" $*

This might not be what you want, of course. As we were putting spaces in the parameters in the above examples you may prefer this:

#!/bin/bash

printf "%s\n" "$@"

Basically, if you give printf more arguments than it needs it will use as many as it can and then repeat with the next set until the list is exhausted. So if you wanted to print two parameters per line, use

printf "%s %s\n"

instead.

Andrew

thanks, I'll try your approach .

I am still trying to understand how bash code is executed.
Perhaps my perception of code line executing "left to right" is basically wrong.

Look at line #277
Every "manual" I read about using "wc" states it "prints".

I do not need "print" - I need to process what I am used to call "function return value".
OK, I understand 'wc" "prints" most likely to some "stdxxx" - as output of "pipe" .
So how does lineCount value , being at the "front" of the pipe get assigned?
And why is the file to be analyzed at the "end" of the code line?

echo "$LINENO test for actual file contents" 
 277 lineCount=$(wc -l < "$PWD$DEBUG_DIR$DEBUG_MENU")
 278 echo "line count $lineCount"
 279 if [ lineCount = 0 ] 
 280 then
 281    echo "$LINENO File $DEBUG_MENU   empty "
 282    #build defaukt menu in file 
 283    defaultMenu
 284    pause 
 285 else 
 286     echo "$LINENO File $DEBUG_MENU   has data  "
 287     pause 
 288 fi




Most of us have learnt this over many years, and I know I'm still learning! You are trying to be as knowledgeable in a matter of weeks.

and by prints they mean "send its results to the Standard Output stream"

The problem is bash uses other programs, such as awk, test and wc, the same way languages like C and Python use functions. But as these programs are meant to return their "values" to the terminal for a person to read, you can't just have

lineCount=wc "somefile"

Process Substitution is used to get over this problem. You know that with Parameter Substitution

var1="Dave"
var2="${var1}"

the string ${var1} is replaced with the value of var1 , i.e. Dave , and assigned to var2 . In the same way,

lines=$(wc -l <myfile)

will replace the string $(wc -l <myfile) with its "value", i.e. the string it attempts to send to the terminal.

I hope that helps.

Andrew