我们可以迭代一组项目,一次考虑一个,如下所示:
#!/bin/bash
for i in $( ls ); do
echo item: $i
done
我们如何在类似的循环中一次处理多个项目?类似的东西:
#!/bin/bash
for i,j,k in $( ls ); do
echo item i: $i
echo item j: $j
echo item k: $k
done
第二个shell脚本不正确,但应准确说明我想要实现的目标。
答案 0 :(得分:4)
假设您没有太多多项(尽管shell应该能够。) 处理不少位置论点。
# Save the original positional arguments, if you need them
original_pp=( "$@" )
set -- *
while (( $# > 0 )); do
i=$1 j=$2 k=$3 # Optional; you can use $1, $2, $3 directly
...
shift 3 || shift $# # In case there are fewer than 3 arguments left
done
# Restore positional arguments, if necessary/desired
set -- "${original_pp[@]}"
对于POSIX兼容性,请使用[ "$#" -gt 0 ]
而不是((...))
表达式。以POSIX兼容的方式保存和恢复所有位置参数没有简单的方法。 (除非有一个字符,否则您可以使用它将它们明确地连接成一个字符串。)
以下是jm666提到的子shell:
(
set -- *
while [ "$#" -gt 0 ]; do
i=$1 j=$2 k=$3
...
shift 3 || shift $#
done
)
子shell退出后,您在子shell中设置的参数的任何更改都将丢失,但上述代码与POSIX兼容。
答案 1 :(得分:3)
如果文件名不包含空格:
find . -maxdepth 1 | xargs -L 3 | while read i j k; do
echo item i: $i
echo item j: $j
echo item k: $k
done
修改强>
我删除了-print0
和-0
。
答案 2 :(得分:1)
要获得to get n items a time from the list
,我认为您希望从数组中获取n
个项目。
像这样使用:
n=3
arr=(a b c d e)
echo "${arr[@]:0:$n}"
a b c
答案 3 :(得分:1)
迟到的回答,我会以非壮观的方式做到这一点:),如:
while read -r -d $'\0' f1
do
read -r -d $'\0' f2
read -r -d $'\0' f3
echo "==$f1==$f2==$f3=="
done < <(find test/ ... findargs... -print0)
答案 4 :(得分:0)
以下是典型编程方式的另一种解决方案 - &gt;
#!/bin/bash
shopt -s nullglob
arr=(*) #read the files/dirs in an array
total=${#arr[@]} #get the array size
count=0;
#loop it thru in multiples of three
while [ $count -lt $((total-2)) ]
do
echo "i is ${arr[$count]}"
echo "j is ${arr[$((count+1))]}"
echo "k is ${arr[$((count+2))]}"
count=$((count+3))
done
#print the remaining element(s)
rem=$((total%3));
if [ $rem -eq 1 ];
then
echo "i is ${arr[$total-1]}"
elif [ $rem -eq 2 ];
then
echo "i is ${arr[$total-2]}"
echo "j is ${arr[$total-1]}"
fi
echo "Done"
答案 5 :(得分:0)
如果你有GNU Parallel,你可以运行:
ls | parallel -N3 "echo item i: {1}; echo item j: {2}; echo item k: {3}"
所有新计算机都有多个内核,但大多数程序本质上是串行的,因此不会使用多个内核。但是,许多任务都非常可并行化:
GNU Parallel是一个通用的并行程序,可以很容易地在同一台机器上或在你有ssh访问权限的多台机器上并行运行作业。
如果要在4个CPU上运行32个不同的作业,并行化的直接方法是在每个CPU上运行8个作业:
GNU Parallel会在完成后生成一个新进程 - 保持CPU处于活动状态,从而节省时间:
<强>安装强>
个人安装不需要root访问权限。这可以在10秒内完成:
(wget -O - pi.dk/3 || curl pi.dk/3/ || fetch -o - http://pi.dk/3) | bash
有关其他安装选项,请参阅http://git.savannah.gnu.org/cgit/parallel.git/tree/README
了解详情
查看更多示例:http://www.gnu.org/software/parallel/man.html
观看介绍视频:https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1
完成教程:http://www.gnu.org/software/parallel/parallel_tutorial.html
注册电子邮件列表以获得支持:https://lists.gnu.org/mailman/listinfo/parallel
答案 6 :(得分:-1)
您可以使用xargs
,awk
,sed
或paste
重新构建输入。
job_select()
{
ls
}
job_process()
{
while read i j k; do
printf 'item i: %s\nitem j: %s\nitem k: %s\n' "$i" "$j" "$k"
done
}
job_restructure_xargs()
{
xargs -L 3
}
job_rstructure_awk()
{
awk '(NR % 3 == 1) { i = $0 } (NR % 3 == 2) { j = $0 } (NR % 3 == 0){ k = $0; print(i,j,k)}'
}
job_restructure_sed()
{
sed -e 'N;N;s/\n/ /g'
}
job_restructure_paste()
{
paste - - -
}
然后是任何组合
job_select | job_restructure_xargs | job_process
job_select | job_restructure_awk | job_process
job_select | job_restructure_sed | job_process
job_select | job_restructure_paste | job_process
做你想做的事。