The following is to be implemented in a BASH script. I have access to what I think are other "devices" commonly used in bash scripts such as sed, awk, bc, dc etc. I have an array whose elements are strings. The elements are either "none" or a name. This question is in 2 parts. The first goes over the simplest form of the problem with as little background as possible. It is all that is needed I think. The second part is almost entirely background on what I am trying to do in general and may be useful, but I do not think is needed necessarily.
以下内容将在BASH脚本中实现。我可以访问我认为在bash脚本中常用的其他“设备”,例如sed,awk,bc,dc等。我有一个数组,其元素是字符串。元素是“无”或名称。这个问题分为两部分。第一种是尽可能少的背景来解决问题的最简单形式。我认为这就是我需要的一切。第二部分几乎完全是关于我一般要做的事情的背景,可能有用,但我不认为是必要的。
Part 1: SHORT VERSION
I have an array of strings
我有一个字符串数组
An example of this array is
这个数组的一个例子是
array=('none' 'none' 'name1' 'none' 'name2' 'none' 'name3' 'none' 'name4')
In my problem the array is much longer. I would like to search if specific elements are 'none' or 'name#' (i.e., not 'none'). AND What I need is to start at element i and check every nth element after that to see if it is 'none' or 'name#' and print all elements that are 'name#' on one line
在我的问题中,数组更长。我想搜索特定元素是'none'还是'name#'(即,不是'none')。 AND我需要的是从元素i开始并检查之后的每个第n个元素,看它是'none'还是'name#'并在一行上打印所有'name#'元素
For this example that means if I want to output starting from say element 2 (array starts at 0) and then checking every 3rd element after that: my output for this would be name1 name4
对于这个例子,这意味着我想从say元素2开始输出(数组从0开始),然后检查后面的每个第3个元素:我的输出为name1 name4
if I had started at element 1 then my output would have been name3
如果我从元素1开始,那么我的输出将是name3
I do not understand piping sufficiently well to be able to echo with a condition (2 conditions really, the first being the periodic range of elements, the second the name vs none criteria).
我不太了解管道能够回应条件(实际上是2个条件,第一个是元素的周期性范围,第二个是名称与无条件)。
Part 2: LONGER VERSION (NOT NECCESSARY)
I am running a double do loop that calls a program. every once in a while the output is not what I want, so I flag the run name and part of that run that I didn't like. I have this criteria set up it saves the "i" "j" in the name so I know where the failure occurred.
我正在运行一个调用程序的双do循环。每隔一段时间输出就不是我想要的,所以我标记了运行名称和我不喜欢的那部分运行。我有这个标准设置它在名称中保存“i”“j”所以我知道故障发生的位置。
Since bash does arrays and not matrices, I save these failed states in an array that is i * j long. This is why I need to access a certain section. If each run has 3 parts, then in post analysis, for that run, I search the elements that correspond to that loop. i.e. if there are 3 runs with 3 parts in each, then in my array elements 0-2 are run 1, 3-5 are run 2, and 6-8 are run 3. This corresponds to the array I have shown above.
由于bash是数组而不是矩阵,我将这些失败状态保存在i * j long的数组中。这就是我需要访问某个部分的原因。如果每次运行有3个部分,那么在后期分析中,对于该运行,我搜索与该循环对应的元素。即如果有3次运行,每次运行3个部分,则在我的阵列中运行元素0-2,运行2到3-5,运行6到6。这对应于我上面所示的阵列。
each run has a part 1, 2 and 3 in this example, or in bash syntax a part 0,1 and 2. (i.e. elements 0,3,6 is the first parts of runs 0 1 2 respectively in the above array, 1,4,7 is the second parts of runs 0,1,2 respectively, and elements 2,5,8 are the 3rd parts of runs 0,1,2 respectively). For each set of parts I want to print out all elements corresponding to those parts that are not 'none'
每次运行在本例中都有第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的第3部分)。对于每组零件,我想打印出与那些不是“无”的零件相对应的所有元素
Here is a dummy code snippet of the process (and this works fine, the question pertains to the post analysis part after)
这是一个过程的虚拟代码片段(这个工作正常,问题属于后分析部分)
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
Now for post analysis, I want to know for a given part, which runs failed. i.e for a given "j" what were the runnames of the "i's" that failed
现在进行后期分析,我想知道一个给定的部分,哪个运行失败。即对于给定的“j”,失败的“我”的运行名称是什么
Post analysis (and my issue. The code is a sorry attempt to convey the idea, it is really more of a pseudo code, it is not bash)
发布分析(和我的问题。代码是一个遗憾的尝试传达的想法,它真的更多的是伪代码,它不是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 个解决方案
#1
1
I don't know if it solves your problem but I think that it would be something close to this.
我不知道它是否解决了你的问题,但我认为这将是接近这一点。
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
This will output:
这将输出:
array size = 9
step = 3
i = 0: [ name3 ]
i = 1: [ name2 ]
i = 2: [ name1 name4 ]
This works by using a nested loop to check for the indexes of the form $i + n * $step.
这通过使用嵌套循环来检查$ i + n * $步骤形式的索引。
You could, of course, change the way it's printing the values to suit your use case. I hope it answers at least the short version of your question!
当然,您可以更改打印值以适合您的用例的方式。我希望它至少回答你的问题的简短版本!
#2
2
If I understood the question correctly, you could emulate a matrix with an associative array and make your code much more readable:
如果我正确理解了这个问题,你可以模拟一个带有关联数组的矩阵,让你的代码更具可读性:
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
1
I don't know if it solves your problem but I think that it would be something close to this.
我不知道它是否解决了你的问题,但我认为这将是接近这一点。
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
This will output:
这将输出:
array size = 9
step = 3
i = 0: [ name3 ]
i = 1: [ name2 ]
i = 2: [ name1 name4 ]
This works by using a nested loop to check for the indexes of the form $i + n * $step.
这通过使用嵌套循环来检查$ i + n * $步骤形式的索引。
You could, of course, change the way it's printing the values to suit your use case. I hope it answers at least the short version of your question!
当然,您可以更改打印值以适合您的用例的方式。我希望它至少回答你的问题的简短版本!
#2
2
If I understood the question correctly, you could emulate a matrix with an associative array and make your code much more readable:
如果我正确理解了这个问题,你可以模拟一个带有关联数组的矩阵,让你的代码更具可读性:
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% }"