Reputation:
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
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
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