首页 > 解决方案 > 值未分配给数组元素 Bash 脚本

问题描述

我正在处理以下脚本。

  1. 我不明白为什么我无法将值分配给数组,当我打印数组元素时,我只得到 arr[0],其余元素为空

  2. 有没有更有效的方法来匹配从 rt_facts 文件中提取的字段 rt_h 和 rt_f 之间的 l_num ?

$ bash -version GNU bash,版本 4.1.2(1)-release (x86_64-redhat-linux-gnu)

$ cat rt_facts
T5 1 2:8 47:9 44
T14 2 48:8 93:9 44
T15 3 94:8 96:9 1

这是过滤后的文件:

$cat filtered_file
12 4046580009982686 05072021 24692161126100379438583 44442
54 4046580009982686 05072021 24692161126100379438583 44442
95 4046580009982686 05072021 24692161126100379438583 44442

在此脚本中,我尝试使用原始文件中的行号匹配过滤文件中的字符串。

bash-4.1$ vi comb_rt_ct.ksh

#!/bin/bash
rows=1
cols=$(($(cat rt_facts | wc -l) + 1))
declare -a arr #=( $(for i in {1..$cols}; do echo 0; done) )
echo "cols " $cols
for l_num in $(grep '4046580009982686 05072021 24692161126100379438583 44442' filtered_file | cut -d" " -f 1)
do
        arr[0]="4046580009982686 05072021 24692161126100379438583 44442"
        echo "l_num " $l_num
        cat rt_facts | while IFS=" " read -r lineStr
        do
                line=( $lineStr )
                #echo ${line[*]}
                rt_h=$(echo ${line[2]} | cut -d":" -f 1)
                rt_f=$(echo ${line[3]} | cut -d":" -f 1)

                if (( l_num > $rt_h && l_num < $rt_f )); then
                        echo "rt_h rt_f " $rt_h "  " $rt_f
                        echo "line[*] " ${line[*]}
                        i=${line[1]}
                        echo "i " $i
                        if [[ -z "${arr[$i]}" ]]; then
                                echo "empty"
                                arr[$i]=0
                        fi
                        (( arr[$i]++ ))
                        echo "arr[$i] "${arr[$i]}
                        #echo ${line[0]}
                        break
                fi
        done
        echo
done

echo ${arr[@]}
echo ${arr[*]}
echo ${arr[2]}

这是我运行脚本时的输出:

bash-4.1$ sh comb_rt_ct.ksh
cols  4
l_num  12
rt_h rt_f  2    47
line[*]  T5 1 2:8 47:9 44
i  1
empty
arr[1] 1

l_num  54
rt_h rt_f  48    93
line[*]  T14 2 48:8 93:9 44
i  2
empty
arr[2] 1

l_num  95
rt_h rt_f  94    96
line[*]  T15 3 94:8 96:9 1
i  3
empty
arr[3] 1

4046580009982686 05072021 24692161126100379438583 44442
4046580009982686 05072021 24692161126100379438583 44442

重击4.1美元

标签: arraysbash

解决方案


正如@glennjackman 所指出的,需要更新问题以提供一个最小的、可重复的示例;所以我跳过尝试对脚本的意图进行逆向工程(或找出名为 的文件的内容filtered_file),而是专注于一项感兴趣的项目:

cat t_facts | while IFS=" " read
    ...
    <assign_values_to_array>
    ...
done

| while ...调用一个子shell ;新值被分配给arr[]这个子外壳中的数组。

ksh中,当退出子外壳时,新更新的arr[]值(有效地)传递给调用/父进程。

bash,退出子shell时,新更新的arr[]值在返回调用/父进程时被丢弃。

因为 OP 的代码在bash( ) 下运行,所以在退出子 shell 时#!/bin/bash更改会丢失;arr[]这反过来意味着调用/父进程“仍然”在 中具有相同的初始值arr[],即:

arr[0]="4046580009982686 05072021 24692161126100379438583 44442"


解决此问题的一种方法,应该适用于kshand bash

while IFS=" " read
    ...
    <assign_value_to_array>
    ...
done < t_facts

这消除了子shell 调用,因此允许在主进程中进行新的数组分配。



同样,我没有尝试理解脚本的整体逻辑,但是 fwiw ...我建议 OP 对while循环进行建议的代码更改(以消除子外壳调用)以查看arr[]数组是否填充了期望的结果。


推荐阅读