【问题标题】:The ever changing variable不断变化的变量
【发布时间】:2021-08-20 14:58:22
【问题描述】:

我正在尝试使用文件中的数据重命名变量。文件的每一行都有一个数字 1-26。我需要读取该值并将其用作变量的一部分以供以后计算。我将有 26 个不同的变量来手动输入(我这样做了)。所以 1 将是 $n1 | 2 将是 $n2 等等,直到 $n26。简而言之,我想读取每个值并让该值创建变量名 [$n(read line

#!/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

【问题讨论】:

  • 我会为此使用不同的语言。 bash 旨在运行其他处理数据的程序,而不是处理数据本身。
  • 我下周开始 C。只是复习逻辑和流程。这只是一个小小的修补项目,可以再次适应一切。应该是可以实现的吧?您可以在变量中包含变量还是应该说是变量的一部分?
  • 对于像这样简单的事情,您可能可以使用数组。但是 shell 数组更多地用于以保留空格的方式存储任意参数,而不是作为数据结构。
  • 你可以使用动态命名的变量吗?当然(谷歌搜索应该会提出相当多的主题);但在这种情况下,使用数组(例如for i in {1..26}; do a[$i]=0; done((n[$line]++))((n[line]++)))可能会更容易(“更好”?)
  • 好的。说得通。感谢您的快速回复。我很感激。所有好的回答者。

标签: bash


【解决方案1】:

您可以使用单个数组来存储您的计数器,文件值行充当索引。

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

【讨论】:

    【解决方案2】:

    只使用数组。

    如果您想动态生成变量名,这是可能的,但有很多注意事项。

    以下脚本显示了这两个选项。在标准输入上给它你的文件poWer

    #!/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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-16
      • 2020-10-04
      • 2021-07-18
      • 2020-12-15
      • 1970-01-01
      相关资源
      最近更新 更多