使用BASH

时间:2018-06-23 05:07:05

标签: arrays bash

以下将在BASH脚本中实现。我可以访问我认为是bash脚本中常用的其他“设备”,例如sed,awk,bc,dc等。我有一个数组,其元素为字符串。元素可以是“无”或名称。这个问题分为2部分。第一种以尽可能少的背景介绍了最简单的问题形式。我认为这就是所需要的。第二部分几乎完全是我要尝试做的事情的背景,可能很有用,但我认为不一定需要。

第1部分:简短版本

我有一个字符串数组

此数组的一个示例是

array=('none' 'none' 'name1' 'none' 'name2' 'none' 'name3' 'none' 'name4')

在我的问题中,数组更长。我想搜索特定元素是否为“ none”或“ name#”(即不是“ none”)。 AND我需要的是从元素i开始,然后检查每个第n个元素,以查看它是'none'还是'name#'并在一行上打印所有'name#'的元素

对于此示例,这意味着如果我要从说元素2(数组从0开始)开始输出,然后在此之后检查每个第3个元素:     我的输出是name1 name4

如果我从元素1开始,那么我的输出应该是name3

我对管道的理解还不够好,无法满足某种条件(实际上是2个条件,第一个条件是元素的周期性范围,第二个条件是名称vs无条件)。

第2部分:更长的版本(非必需)

我正在运行一个调用程序的double do循环。有时输出不是我想要的,所以我标记了运行名称和我不喜欢的运行的一部分。我已经设置了此条件,它将名称中的“ i”“ j”保存了下来,所以我知道发生故障的地方。

由于bash会处理数组而不是处理矩阵,因此我将这些失败的状态保存在i * j长的数组中。这就是为什么我需要访问特定部分的原因。如果每个运行包含3个部分,则在后分析中,对于该运行,我搜索与该循环对应的元素。例如,如果有3个运行,每个运行3个部分,则在我的数组元素0-2中运行1,在3-5中运行2,在6-8中运行3。这对应于我上面显示的数组。 / p>

在此示例中,每个运行具有部分1、2和3,或者在bash语法中具有部分0,1和2(即,元素0,3,6分别是上面运行0 1 2的第一部分)数组1,4,7分别是行程0,1,2的第二部分,而元素2,5,8分别是行程0,1,2的第三部分)。对于每组零件,我想打印出与那些不是“无”的零件相对应的所有元素

这是该过程的伪代码段(并且工作正常,问题与之后的后期分析部分有关)

k=0
for ((i=0 ; i<$NRuns ; i++)); do
    for ((j=0 ; j<$NPartsPerRun ; j++)); do
        k=$((k + 1))
        #PSEUDO CODE HERE not actual bash
        call program
        if "program output bad" ; then
            array[$k]=$Runname
        else
            echo "Thanks for taking the time to look at my problem"
        fi
    done
done

现在要进行后期分析,我想知道给定零件的运行失败。即对于给定的“ j”,失败的“ i”的运行名称是什么

事后分析(还有我的问题。该代码是传达这一想法的遗憾尝试,它实际上更多是伪代码,不是bash)

for ((i=0 ; i<$NPartsPerRun ; i++)); do
    #PSEUDO CODE HERE not actual bash
    #first element to check is $i, then check every Xth element
        if ${array[$i]} || ${array[$(i+X)]} etc.. != 'none' echo "element names that pass condition test"
        fi
    done
done   

2 个答案:

答案 0 :(得分:3)

如果我正确理解了这个问题,则可以模拟一个具有关联数组的矩阵,并使代码更具可读性:

declare -A matrix=()

# save runs into the matrix
for ((i=0; i<n_runs; i++)); do
    for ((j=0; j<n_parts; j++)); do
        [[ $(program) = bad ]] && matrix[$i,$j]=$name
    done
done

# print unsuccessful runs for a given part
part=2 runs=

for ((i=0; i<n_runs; i++)); do
    [[ ${matrix[$i,$part]} ]] && runs+="${matrix[$i,$part]} "
done

printf '%s\n' "${runs% }"

答案 1 :(得分:2)

我不知道它是否可以解决您的问题,但我认为这可能与之接近。

array=('none' 'none' 'name1' 'none' 'name2' 'none' 'name3' 'none' 'name4')
step=3

echo "array size = ${#array[@]}"
echo "step = $step"

for ((i= 0; i < step; i += 1)); do
    echo -ne  "i = $i: [ "
    for ((j = i; j < ${#array[@]}; j += step)); do
        if [[ "${array[$j]}" != "none" ]]; then
            echo -n "${array[$j]} "
        fi
    done
    echo "]"
done

这将输出:

array size = 9
step = 3
i = 0: [ name3 ]
i = 1: [ name2 ]
i = 2: [ name1 name4 ]

这通过使用嵌套循环来检查$ i + n * $ step形式的索引来工作。

您当然可以更改打印值的方式以适合您的用例。我希望它至少能回答您问题的简短版本!