user16714218
user16714218

Reputation:

The ever changing variable

What I am attempting to do is rename a variable with data from a file. On each line of the file is a number 1-26. I need to read the value and use it as part of the variable for later calculations. I would have 26 different variables to manually type out(which I did). So 1 would be $n1 | 2 would be $n2 and so on up to $n26. In short I want to read each value and have that value create the variable name [ $n(read line < filename.txt) ]. If the first value is 16 $n16. What I have done is taken the crazy long way and I am working on a second one that is 1-69. So how do you make a dynamic variable that has a variable that is determined by each line of data from a file. I typed each variable, ran it through a case statement for the counts and then echoed the totals( all again typed out 26 variable names) and still have averages to do for each one. Thanks for any idea's and help. I will post my mess of a script when I can switch back over to Linux which is where it is saved.

#!/bin/bash
#
#### Author Joseph S ####
#
### HN probabilities ###
#
 clear 
# Need a easy way to intialize all of these variables
n1=0 
n2=0
n3=0
n4=0
n5=0
n6=0
n7=0
n8=0
n9=0
n10=0
n11=0
n12=0
n13=0
n14=0
n15=0
n16=0
n17=0
n18=0
n19=0
n20=0
n21=0
n22=0
n23=0
n24=0
n25=0
n26=0
while read -r line;
do
COUNTER=`expr $COUNTER + 1`
case $line in
    1 ) n1=$(( $n1 + 1 ));;
    2 ) n2=$(( $n2 + 1 ));;
    3 ) n3=$(( $n3 + 1 ));;
    4 ) n4=$(( $n4 + 1 ));;
    5 ) n5=$(( $n5 + 1 ));;
    6 ) n6=$(( $n6 + 1 ));;
    7 ) n7=$(( $n7 + 1 ));;
    8 ) n8=$(( $n8 + 1 ));;
    9 ) n9=$(( $n9 + 1 ));;
    10 ) n10=$(( $n10 + 1 ));;
    11 ) n11=$(( $n11 + 1 ));;
    12 ) n12=$(( $n12 + 1 ));;
    13 ) n13=$(( $n13 + 1 ));;
    14 ) n14=$(( $n14 + 1 ));;
    15 ) n15=$(( $n15 + 1 ));;
    16 ) n16=$(( $n16 + 1 ));;
    17 ) n17=$(( $n17 + 1 ));;
    18 ) n18=$(( $n18 + 1 ));;
    19 ) n19=$(( $n19 + 1 ));;
    20 ) n20=$(( $n20 + 1 ));;
    21 ) n21=$(( $n21 + 1 ));;
    22 ) n22=$(( $n22 + 1 ));;
    23 ) n23=$(( $n23 + 1 ));;
    24 ) n24=$(( $n24 + 1 ));;
    25 ) n25=$(( $n25 + 1 ));;
    26 ) n26=$(( $n26 + 1 ));;
esac 
done < poWer
echo $n1 $n2 $n3 $n4 $n5 $n6 $n7 $n8 $n9 $n10 $n11 $n12 $n13 $n14 $n15 $n16 $n17 $n18 $n19 $n20 $n21 $n22 $n23 $n24 $n25 $n26 > MaP 
per=$(echo "scale=4; $n1/$COUNTER" | bc ) # This line needs to cycle through all 26 variables when file is done#
#echo -e "\n\n\t  $per percent out of $COUNTER lines" > MaP;
done

Upvotes: 0

Views: 89

Answers (2)

Andrej Podzimek
Andrej Podzimek

Reputation: 2778

Just use arrays.

If you want to generate variable names dynamically, this is possible, but there are numerous caveats to it.

The following script shows both options. Give it your file poWer on standard input.

#!/bin/bash
set -e -o pipefail  # good practice in general

# Some integer declarations for clarity.
declare -ai counts
declare -i line i sum

# Read the file and count individual numbers.
while read line; do ((++counts[line])); done

# Calculate the sum.
for i in "${counts[@]}"; do ((sum += i)); done

# Report the results.
for i in "${!counts[@]}"; do
  echo "$((i)) read $((counts[i])) times" \
       "(roughly $(((100 * counts[i] + sum / 2) / sum))%" \
       "of $((sum)))"
done

# Store the counts also into separate variables for no good reason.
for i in "${!counts[@]}"; do
  declare -i "n$((i))"="$((counts[i]))"
done

# Read the new separate variables created above for no good reason.
for var in "${!n@}"; do
  echo "variable ${var} set to ${!var}"
done

Upvotes: 0

chepner
chepner

Reputation: 531235

You can use a single array to store your counters, with the file values line acting as the index.

ns=()
for((i=1; i<=26; i++)); do
  ns[$i]=0
done

while read -r line; do
  ((counter++))
  ((ns[$line]++))
done < poWer

echo "${ns[*]}" > MaP  # Expand to a single string, array elements separated by a space.
for i in "${ns[@]}"; do  # Expand to a sequence of multiple elements
  per=$(echo "scale=4; $i/$counter" | bc )
  printf '\n\n\t  %s percent out of %s lines" "$per" "$counter"
done >> MaP

Upvotes: 1

Related Questions