大佬教程收集整理的这篇文章主要介绍了如何在bash中的for循环中添加分组机制 将for ... in改为while read一次读 3 个并行运行脚本,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一个循环遍历文件列表的 for 循环,在 for 循环中调用了一个脚本,该脚本将这个文件名作为输入。 类似的东西
for file in $(cat List_of_files) ; do
script $file
done
文件 List_of_files
有类似的文件
file1
file2
file3
...
所以每次迭代都会处理一个文件。
我必须设计类似的东西,循环遍历所有文件,将它们分组为 3 组,这样在一个循环中,脚本将被调用 3 次,而不是一一调用,然后其他 3 次将再次调用在第二次循环迭代中调用,依此类推
类似的东西,
for file in $(cat List_of_files) ; do
# do somekind of grouPing here
call one more loop to run the sript.sh 3 times,so something like
for i=1 to 3 and then next iteration from 4 to 6 and so on..
script.sh $file1
script.sh $file2
script.sh $file3
done
我目前正在为如何完成这个循环而苦苦挣扎,我被困在这里,无法在这里想出有效的方法。
for ... in
改为while read
for file in $(cat list_of_files)
这种循环方式非常危险和/或不正确。它不适用于带有空格、星号或其他特殊字符的文件名。作为一般规则,避免 for x in $(...)
循环。有关更多详细信息,请参阅:
for f in $(ls *.mp3)
。更安全的替代方法是将 while read
与 process substitution 一起使用,如下所示:
while IFS= read -r file; do
...
done < <(cat list_of_files)
我承认这很丑陋,但它可以安全地处理特殊字符。它用空格分隔文件名,并且不会扩展 *
globs。有关此操作的更多详细信息,请参阅:
然后您可以删除 U@R_772_10288@ss Use of Cat 并改用简单的重定向:
while IFS= read -r file; do
...
done < list_of_files
到目前为止,这些更改还没有回答您的核心问题,即如何一次对 3 个文件进行分组。切换到 read
实际上还有第二个目的。它使分组变得容易。诀窍是每次迭代多次调用 read
。这是 while read
的一个简单更改; for ... in
并不容易。
这是它的样子:
while IFS= read -r file1 &&
IFS= read -r file2 &&
IFS= read -r file3
do
script.sh "$file1"
script.sh "$file2"
script.sh "$file3"
done < list_of_files
这将调用 read
三次,一旦这三个都成功,它就会进入循环体。
如果您总是有 3 个项目的倍数需要处理,它会很有效。如果没有,它会在最后搞砸并跳过最后一个或两个文件。如果这是一个问题,我们可以更新它以尝试处理这种情况。
while IFS= read -r file1; do
IFS= read -r file2
IFS= read -r file3
script.sh "$file1"
[[ -n $file2 ]] && script.sh "$file2"
[[ -n $file3 ]] && script.sh "$file3"
done < list_of_files
如果我理解您的问题是正确的,您还希望同时运行脚本而不是按顺序运行脚本,一个接一个。如果是这样,这样做的方法是附加 &
,这将导致它们在后台运行。然后调用 wait
阻止,直到他们都完成后再继续。
while IFS= read -r file1; do
IFS= read -r file2
IFS= read -r file3
script.sh "$file1" &
[[ -n $file2 ]] && script.sh "$file2" &
[[ -n $file3 ]] && script.sh "$file3" &
wait
done < list_of_files
,
怎么样
xargs -d $'\n' -L 1 -P 3 script.sh <list_of_files
-P 3
并行运行 3 个进程。每个都获得一行的输入(由于 -L 1
),而 -d
选项确保输入行中的空格不被视为单独的参数。
您可以使用 bash 数组来存储文件名,直到获得 3 个:
#!/bin/bash
files=()
while IFS= read -r f; do
files+=( "$f" )
(( ${#files[@]} < 3 )) && conTinue
script.sh "${files[0]}"
script.sh "${files[1]}"
script.sh "${files[2]}"
files=()
done < list_of_files
但是,我认为 John Kugelman 的答案更简单,然后更好:它使用较少的 bash 特定功能,然后可以更轻松地将其转换为 POSIX 版本。
,如果你不是绝对必须,你不应该混合脚本语言
你可以从那个开始
from os import listdir
from os.path import isfile,join
PATH_FILES = "/yourfolder"
def yourFunction(file_name):
file_path = PATH_FILES + "/" + file_name
print(file_path) #or do something else
print(file_path) #or do something else
print(file_path) #or do something else
file_names = [f for f in listdir(PATH_FILES) if isfile(join(PATH_FILES,f))]
for file_name in file_names:
yourFunction(file_name)
,
如果 @H_952_5@mapfile 又名 readarray
可用/可接受。 (需要bash4+)
假设 script.sh
可以接受多个输入。
#!/usr/bin/env bash
while mapfile -tn3 files && (( ${#files[*]} == 3 )); do
script.sh "${files[@]}"
done < list_of_files
否则循环遍历名为 files
的数组
#!/usr/bin/env bash
while mapfile -tn3 files && (( ${#files[*]} == 3 )); do
for file in "${files[@]}"; do
script.sh "$file"
done
done < list_of_files
do
之后的正文如果总是有 3 行,就会运行/执行,如果直到文件末尾没有足够的行来满足 3 行,只需删除
&& (( ${#files[*]} == 3 ))
来自脚本。
或者手动一一执行,但它应该有 3 行要处理(文件)直到结束。
#!/usr/bin/env bash
while mapfile -tn3 files && (( ${#files[*]} == 3 )); do
script.sh "${file[0]}"
script.sh "${file[1]}"
script.sh "${file[2]}"
done < list_of_files
以上是大佬教程为你收集整理的如何在bash中的for循环中添加分组机制 将for ... in改为while read一次读 3 个并行运行脚本全部内容,希望文章能够帮你解决如何在bash中的for循环中添加分组机制 将for ... in改为while read一次读 3 个并行运行脚本所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。