如何循环遍历 Bash 中列表的特定元素?
How can I loop through specific elements of a list in Bash?
我有一个文件列表存储在通过输入
获得的变量中
files="./*.fasta"
我想创建一个 for 循环,它将循环遍历:例如前 200 个元素、元素 201-400、元素 401-578。
我怎样才能做到这一点?我试过
for file in $files[1-200]; do
echo $file
done
但这显然行不通。
不推荐使用变量填充文件列表。最好的方法是使用数组!
您需要通过 shopt -s nullglob
启用 shell 选项来避免空 glob 扩展,这样如果没有找到文件,for-loop 就会正常退出。下面的示例显示了一次迭代 200 个文件。您可以根据需要更改索引,以便在 for-loop 中根据需要从 200-400 和 400-600 打印。
shopt -s nullglob
files=(*.fasta)
if (( "${#files}" >= 200 )); then
for ((i=0; i<200; i++)); do
printf '%s\n' "${files[i]}"
done
fi
将它们放在一个数组中,然后使用子字符串扩展来获取批量文件。
files=(./*.fasta)
for ((i=0; i< ${#fasta[*]}; i+=200)); do
process "${files[@]:i:200}" &
done
问题的解决方法可能有所不同。您可以使用 find
和 xargs
:
而不是使用 for 循环
find * -name '*.fasta' -maxdepth 0 -print0 | xargs -0 -n 200 -P 0 echo
find
将每个文件名传递给 xargs
,后者又为每 200 个输入文件 (-n 200
) 生成一个进程 (-P 0
)。
此 one-liner 使用 -print0
和 -0
标记以防您的文件名包含空格。
在这种情况下,for 循环构造不太理想。
或者,您可以使用 while 循环和内置的 readarray:
find * -name '*.fasta' -maxdepth 0 | while readarray -n 3 a && [[ ${#a} -ne 0 ]]
do
echo ${a[@]}
done
我有一个文件列表存储在通过输入
获得的变量中files="./*.fasta"
我想创建一个 for 循环,它将循环遍历:例如前 200 个元素、元素 201-400、元素 401-578。
我怎样才能做到这一点?我试过
for file in $files[1-200]; do
echo $file
done
但这显然行不通。
不推荐使用变量填充文件列表。最好的方法是使用数组!
您需要通过 shopt -s nullglob
启用 shell 选项来避免空 glob 扩展,这样如果没有找到文件,for-loop 就会正常退出。下面的示例显示了一次迭代 200 个文件。您可以根据需要更改索引,以便在 for-loop 中根据需要从 200-400 和 400-600 打印。
shopt -s nullglob
files=(*.fasta)
if (( "${#files}" >= 200 )); then
for ((i=0; i<200; i++)); do
printf '%s\n' "${files[i]}"
done
fi
将它们放在一个数组中,然后使用子字符串扩展来获取批量文件。
files=(./*.fasta)
for ((i=0; i< ${#fasta[*]}; i+=200)); do
process "${files[@]:i:200}" &
done
问题的解决方法可能有所不同。您可以使用 find
和 xargs
:
find * -name '*.fasta' -maxdepth 0 -print0 | xargs -0 -n 200 -P 0 echo
find
将每个文件名传递给 xargs
,后者又为每 200 个输入文件 (-n 200
) 生成一个进程 (-P 0
)。
此 one-liner 使用 -print0
和 -0
标记以防您的文件名包含空格。
在这种情况下,for 循环构造不太理想。
或者,您可以使用 while 循环和内置的 readarray:
find * -name '*.fasta' -maxdepth 0 | while readarray -n 3 a && [[ ${#a} -ne 0 ]]
do
echo ${a[@]}
done