对列表上的循环进行批处理



我正在尝试bash脚本,它根据列表的大小以批处理模式执行以下javajar命令。

我有一个包含美国54个州的字符串列表。

list = [USA+CA,USA+TX,USA+TN...]

我需要并行执行下面的命令,4个实例有4个值作为列表的输入。

java -jar test-execute.jar --localities=USA+TX,USA+CA,USA+TN,USA+AB

等待任何实例的执行完成,然后用接下来的4个状态启动jar的新实例。

array=( USA+TX,USA+CA,USA+TN,USA+AB )
for i in "${array[@]}"
do
java -jar test-execute.jar --localities= ???
done

我无法理解如何动态地将数组中的输入提供给jar执行。

所以,

我有54号的清单,

我需要并行运行4个java实例,每个实例都有4个唯一的状态作为54的列表中的输入,一旦这些实例完成,然后启动接下来的4个实例,每个实例具有接下来唯一的4个状态。

更新:

我有54个州的清单,16个核心机器。每个javajar实例将使用4个核心,因此我可以一次运行4个java实例来使用16核心机器。

16 core machine 
java instance-1 4 states
java instance-2 4 states
java instance-3 4 states
java instance-4 4 states

wait till any of these instances complete, once completed, start new instance with next 4 states until all 54 states has been executed. 

请帮忙。

首先,bash array必须以空格分隔的列表形式分配为:

array=("USA+AL" "USA+AK" "USA+AZ" "USA+AR" "USA+AS" "USA+CA" ...)

那么你能试试这样的东西吗:

array=("USA+AL" "USA+AK" "USA+AZ" "USA+AR" "USA+AS" "USA+CA" ...)
for (( i = 0; i < ${#array[@]}; i+=4 )); do
echo java -jar test-execute.jar --localities="$(IFS=,; echo "${array[*]:i:4}")"
done
  • for循环具有类似C的语法,用于将索引增加值4
  • 阵列切片${array[*]:i:4}将阵列划分为子阵列从第i个索引开始的每四个元素。带有两个元素的最后一个块也会被处理
  • $(IFS=,; echo "${array[*]:i:4}")使用逗号连接数组馈送到CCD_ 5作为自变量

如果输出看起来不错,将echo放在java前面。

[Edit]
至于并行性,我们可以使用-P选项到xargs。你能试试吗:

array=("USA+AL" "USA+AK" "USA+AZ" "USA+AR" "USA+AS" "USA+CA" ...)
for (( i = 0; i < ${#array[@]}; i+=4 )); do
printf "%sn" "$(IFS=,; echo "${array[*]:i:4}")"
done | xargs -P4 -L1 -I{} java -jar test-execute.jar --localities="{}"
  • 它将四个状态分组为一个参数
  • -P4选项一次生成四个进程
  • 然后一次总共处理16个状态

最新更新