![使用 shell 数组并行读取文件的每 N 行](https://linux22.com/image/189868/%E4%BD%BF%E7%94%A8%20shell%20%E6%95%B0%E7%BB%84%E5%B9%B6%E8%A1%8C%E8%AF%BB%E5%8F%96%E6%96%87%E4%BB%B6%E7%9A%84%E6%AF%8F%20N%20%E8%A1%8C.png)
所以,我已经知道如何成功并行读取每 N 行,并在每一行上运行命令:
while read -r i && read -r a && read -r b && read -r c && read -r d && read -r e && read -r f && read -r g && read -r h && read -r j && read -r k && read -r l && read -r m && read -r n && read -r o && read -r p && read -r q && read -r r && read -r s && read -r t && read -r u && read -r v && read -r w && read -r x && read -r z && read -r aa && read -r bb && read -r cc && read -r dd && read -r ee && read -r ff && read -r gg && read -r hh && read -r ii && read -r jj; do
dosomething "$i" &
dosomething "$a" &
dosomething "$b" &
dosomething "$c" &
dosomething "$d" &
dosomething "$e" &
dosomething "$f" &
dosomething "$g" &
dosomething "$h" &
dosomething "$j" &
dosomething "$k" &
dosomething "$l" &
dosomething "$m" &
dosomething "$n" &
dosomething "$o" &
dosomething "$p" &
dosomething "$q" &
dosomething "$r" &
dosomething "$s" &
dosomething "$t" &
dosomething "$u" &
dosomething "$v" &
dosomething "$w" &
dosomething "$x" &
dosomething "$z" &
dosomething "$aa" &
dosomething "$bb" &
dosomething "$cc" &
dosomething "$dd" &
dosomething "$ee" &
dosomething "$ff" &
dosomething "$gg" &
dosomething "$hh" &
dosomething "$ii" &
dosomething "$jj" &
wait
done < somefile
其中dosomething
只是一个something
处理特定行(由旁边的变量表示)的示例函数/应用程序。
本质上这个工作正常。只是想通过使用数组来使这个工作/看起来更好,但不知道如何格式化它,以便它使用数组......
它会为 N 个作业生成变量名称(只有 alpha,没有数字,因为这可能会给通常的编号变量带来问题,例如 $1 等)。
为了防止混淆:上面脚本中的每次读取都执行“一行”,因此每次读取=一行。这意味着每次迭代都会读取一行 X 的读取量。每次迭代结束时wait
都会等待所有作业完成。
例子:
- 这答案做了与我正在做的类似的事情,除了它同时从两个文件、两行(每行一行)读取。我的功能更多。
PS:我知道我可以使用 或其他东西做得更好parallel
,xargs
但如果可能的话更愿意只使用 bash/POSIX。
任何意见表示赞赏。
答案1
不使用数组,但保留一个计数器来确定何时等待。
count=0
while read -r line; do
dosomething "$line" &
((++count % 35 == 0)) && wait
done < file
顺便说一句,您不喜欢这个变量吗y
?
您的代码存在一个大问题:您必须成功读取所有 35 行dosomething
。在处理文件时,假设您在尝试读取时读取了a
and but hit EOF --返回非零, while 条件失败并且循环在不处理and 的情况下中断。b
c
read
$a
$b
使用数组,并不简单:
mapfile -t lines < file
len=${#lines[@]}
i=0
while ((i < len)); do
for _ in {1..35}; do
dosomething "${lines[i]}" &
((i++))
((i == len)) && break
done
wait
done