0

I tried generating variables dynamically and assigning values to it but I encountered two issues with the code:

  1. I am not able to convert the value of "count" to numeric value so it can be used in for loop
  2. The values of variables are lost after for loop is completed.

Code

filename=$1

count= sed -n 1p $1 | tr ',' '\n' | wc -l

while read line

do

    if [ $i -ne 1 ]; then
        check_Keyword=`echo $line |grep -Eo '\b,Error\b'`
        if [ "$check_Keyword" = ",Error" ]; then
            if [ $post_counter -eq 0 ]; then
                post_counter=$(expr $post_counter + 1)
            else
                write_values
            fi
            temp_text=""
                 for j in $(eval echo {1..count} )
                    do
                        Column[$j]=`echo $line | cut -d ',' -f$j`
                    done 

            temp_text=`echo $line | cut -d ',' -f3`
        else
            temp_text=$line
            
        fi
        msg_identifier=$msg_identifier$temp_text
                            
    fi
i=$(expr $i + 1)
done < $file_name
3
  • sed, tr, wc, while loop, test, grep, expr , cut ... ? .Perhaps you can look for awk. Commented Jul 4, 2018 at 21:15
  • There are a number of problems, but for bash, just use a C-style for loop, e.g. for ((j = 1; j < count; j++)); do .. done. Also just use if [[ $line =~ ,Error ]]; then ... instead of the awkward check_Keyword= and if [ "$check_Keyword" = ",Error" ]. Avoid 'echo ... | cut ...`, bash provides parameter expansions to do just that without spawning multiple additional subshells. Commented Jul 5, 2018 at 3:05
  • 2
    Please use bash -n scriptname and shellcheck.net to analyse your script before questions like this. There are many things that won't work here, and it would be lovely if the question was more along the lines of "why does this generate unexpected output" rather than "please fix and clean my code". Commented Jul 5, 2018 at 6:25

1 Answer 1

1

To answer your first question, you could try something like:

count=$(sed -n 1p $1 | tr ',' '\n' | wc -l)

Or:

count=`sed -n 1p $1 | tr ',' '\n' | wc -l`

=> You need to use a subshell to catch the output and do not put space around =.

To answer your second question about fetching the values of an array outside the loops, let's do this experiment:

$ cat data.txt 
line1
line2
line3
$ while read; do for i in {1..10}; do array[$i]="$REPLY"; done; done < data.txt 
$ echo ${#array[@]}
10
$ echo ${array[@]}
line3 line3 line3 line3 line3 line3 line3 line3 line3 line3
$ while read; do for i in {1..10}; do array[$i]="$REPLY"; done; echo "size=${#array[@]}, content=${array[@]}"; done < data.txt 
size=10, content=line1 line1 line1 line1 line1 line1 line1 line1 line1 line1
size=10, content=line2 line2 line2 line2 line2 line2 line2 line2 line2 line2
size=10, content=line3 line3 line3 line3 line3 line3 line3 line3 line3 line3

What does this show us?

  1. You can read the array values outside the for loop.
  2. You can read the array values outside the while loop either.
  3. You're replacing the offsets of your array every iterations of your while loop.

Then, here's some other errors in your script:

  1. You could use for j in (( i=1 ; i<= $count ; i++ )) instead of for j in $(eval echo {1..count} ) to avoid to use eval echo (and do not forget the $ to get the value).
  2. You could use (( i++ )) instead of i=$(expr $i + 1).
  3. You should protect your variables using doubles quotes like that: msg_identifier="${msg_identifier}${temp_text}" instead of msg_identifier=$msg_identifier$temp_text for example (here's an example of bug when you're not protecting your variables).

Conclusion:

There's many problems in your script (among others the count assignation and the count reading in your for loop), your loops might not have the expected behavior because of those syntax errors.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank You Idriss. But i am still not sure how to dynamically fetch the value of variables of for loop in its outer while loop.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.