名称中带有变量的bash数组

阿隆公司

感谢您在以下问题上的帮助:

我正在尝试设置一个包含变量的数组,该变量作为数组名称的一部分,例如:(Arr_$COUNTER其中$COUNTER根据循环计数进行更改)

我尝试过的所有可能方式都出了错误,例如“错误替换”或“意外令牌附近的语法错误”

这是整个流程:

  1. 一个文件包含多行。每行有6个值,以空格分隔

    10 20 30 40 50 60  
    100 200 300 400 500 600
    
  2. 该脚本旨在从文件中读取每一行,并将其声明为数组(行号为变量)。

  3. 作为测试,应该打印每个值,并最终在每个值上执行另一个功能。

    #!/bin/bash
    COUNTER=1
    LINES=`wc -l VALUES_FILE.txt | awk '{print $1}'`
    echo "Total number of lines "$LINES
    echo
    while [ $COUNTER -le $LINES ]
    do
    echo "Counter value is $COUNTER"
    field=`awk "NR == $COUNTER" VALUES_FILE.txt`
    echo "Field = $field"
    declare -a "arr$COUNTER=($field)"
    echo "arr$COUNTER[0] = ${arr$COUNTER[0]}"
    echo "arr$COUNTER[1] = ${arr$COUNTER[1]}"
    echo "arr$COUNTER[2] = ${arr$COUNTER[2]}"
    echo "arr$COUNTER[3] = ${arr$COUNTER[3]}"
    echo "arr$COUNTER[4] = ${arr$COUNTER[4]}"
    echo "arr$COUNTER[5] = ${arr$COUNTER[5]}"
    let COUNTER=COUNTER+1
    echo
    done
    echo "The End"
    echo
    

结果如下:

行总数2

计数器值为1
字段= 10 20 30 40 50 60 
./sort.sh:第12行:arr $ COUNTER [0] = $ {arr $ COUNTER [0]}:替代错误
结束

为了使其正常工作,应该进行哪些更改/修复?

谢 !

用户名

一些想法:

  1. 变量值的“参数扩展”($ {...}部分):

    echo "arr$COUNTER[0] = ${arr$COUNTER[0]}"
    

    不管用。您可以通过使用eval来解决问题(但我不建议这样做):

    eval echo "arr$COUNTER[0] = \${arr$COUNTER[0]}"
    

    该行可以这样写:

    i="arr$COUNTER[0]"; echo "$i = ${!i}"
    

    在Bash中称为间接寻址(!)。

  2. 此行发生类似的问题:

    declare -a "arr$COUNTER=($field)"
    

    应该分成两行,并使用eval:

    declare -a "arr$COUNTER"
    eval arr$COUNTER\=\( \$field \)
    

    同样,我不建议使用eval(在这种情况下)。

  3. 当您将整个文件读入shell的内存时,我们还可以使用一种更简单的方法将所有行放入数组中:

    readarray -t lines <"VALUES_FILE.txt"
    

    这应该比为每行调用awk更快。

具有以上所有内容的脚本可能是:

#!/bin/bash
valfile="VALUES_FILE.txt"

readarray -t lines <"$valfile"             ### read all lines in.

line_count="${#lines[@]}"
echo "Total number of lines $line_count"

for ((l=0;l<$line_count;l++)); do
    echo "Counter value is $l"             ### In which line are we?
    echo "Field = ${lines[l]}"             ### kepth only to help understanding.
    k="arr$l"                              ### Build the variable arr$COUNTER
    IFS=" " read -ra $k <<<"${lines[l]}"   ### Split into an array a line.
    eval max=\${#$k[@]}                    ### How many elements arr$COUNTER has?
    #echo "field $field and k=$k max=$max" ### Un-quote to "see" inside.
    for ((j=0;j<$max;j++)); do             ### for each element in the line.
        i="$k[$j]"; echo "$i = ${!i}"      ### echo it's value.
    done
done
echo "The End"
echo

但是,如果我们可以执行AWK中您需要的内容,则AWK可能会更快。


可以在awk中完成类似的处理。假设这6个值将用作IP(其中4个),而其他两个则是一个数字和一个纪元时间。

只是AWK脚本的一个非常简单的示例:

#!/bin/sh
valfile="VALUES_FILE.txt"
awk '
NF==6 { printf ( "IP: %s.%s.%s.%s\t",$1,$2,$3,$4)
        printf ( "number: %s\t",$5+2)
        printf ( "epoch: %s\t",$6)
        printf ( "\n" )
    }
' "$valfile"

只需对细节提出一个新问题。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章