Home > Software design >  Filling dynamic array with user input value
Filling dynamic array with user input value

Time:02-15

I am new to shell scripting. I am trying to create an array ,where the string x (as of now i am using static value for testing purpose) will be an input by the user during the run time.

#!/bin/bash
x="101:Redmi:Mobile:15000#102:Samsung:TV:20000#103:OnePlus:Mobile:35000#104:HP:Laptop:65000#105:Samsung:Mobile:10000#106:Samsung:TV:30000"
i=0
index=0 
declare -a categ_array=()
declare  -a amnt_array=()
declare -a cnt_array=()
echo "$x"  | tr '#' '\n' | cut -d ":" -f 3-4 | while read -r line ;
do
  echo "------Inside while loop------"
  echo $line
  category=$(echo "$line" | cut -d ":" -f 1 )
  echo $category
  amount=$(echo "$line" | cut -d ":" -f 2 )
  echo $amount
  echo $i
  categ_array[$i]=${category}
  amnt_array[$i]=${amount}
  cnt_array[$i]=1
  let i =1
  
done

echo Category:
for n in "${categ_array[@]}"
do
 echo $n
done ```      



When I run the above script, I do not get any output. Where as I want output as

``` categ_array should have data as (Mobile,TV,Mobile,Laptop,Mobile,TV) ```                                 
```amnt_array should have data as (15000,20000,35000,65000,10000,30000)```




Can someone tell me where am I going wrong?

CodePudding user response:

The fundamental problem is that the arrays are populated inside a pipeline. Pipeline stages are run in sub-processes so changes to variables made within them are not visible in the main program. See What happens when reading into a variable in a pipeline?.

Since the arrays are populated in the last stage of the pipeline, you can fix the problem if you are running Bash version 4.2 or later by putting

shopt -s lastpipe

in the code before the pipeline. That causes the last stage of the pipeline to be run in the top-level shell so changes to variables are visible after the pipeline completes.

Since you are using Bash, you can do what you want without using pipelines (or external commands like tr and cut). Try this Shellcheck-clean code:

#! /bin/bash -p

x="101:Redmi:Mobile:15000#102:Samsung:TV:20000#103:OnePlus:Mobile:35000#104:HP:Laptop:65000#105:Samsung:Mobile:10000#106:Samsung:TV:30000"

declare -a categ_array=()
declare -a amnt_array=()
declare -a cnt_array=()

while IFS= read -r -d '#' line || [[ -n $line ]]; do
    IFS=: read -r _ _ category amount <<<"$line"

    categ_array =( "$category" )
    amnt_array =( "$amount" )
    cnt_array =( 1 )
done <<<"$x"

echo Category:
for n in "${categ_array[@]}"; do
    echo "$n"
done
  • Related