Bash 脚本一次对 X 个文件运行命令

Bash 脚本一次对 X 个文件运行命令

我目前正在运行 freesurfer,并尝试运行多个recon-all命令。该机器一次只能处理 10 个构建。我想创建一个 bash 脚本,该recon-all脚本对目录中的每个文件运行该命令,但一次只能对 10 个文件运行该命令。

我当前的脚本针对所有文件逐个运行:

for f in *.nii; do
    if [ -f ${f} ]; then
        echo $f
    recon-all -i $f -s $f"DIR" -all > $f"_log3.txt" &
    fi
done

我基本上需要进行设置,以便第 10构建在没有 & 命令的情况下运行,因此它必须等到该构建完成后才能开始接下来的 10 次构建。

有什么建议么?

更新:

以下是解决后的完整代码:

find -type f -name '*.nii' -print0 |xargs -n10 -0 sh -c '
 echo "Running: ${0#./}"
 recon-all -i "$0" -s "$0DIR" -all > "$0_log.txt" &
 echo "Running: ${1#./}"
 recon-all -i "$1" -s "$1DIR" -all > "$1_log.txt" &
 echo "Running: ${2#./}"
 recon-all -i "$2" -s "$2DIR" -all > "$2_log.txt" &
 echo "Running: ${3#./}"
 recon-all -i "$3" -s "$3DIR" -all > "$3_log.txt" &
 echo "Running: ${4#./}"
 recon-all -i "$4" -s "$4DIR" -all > "$4_log.txt" &
 echo "Running: ${5#./}"
 recon-all -i "$5" -s "$5DIR" -all > "$5_log.txt" &
 echo "Running: ${6#./}"
 recon-all -i "$6" -s "$6DIR" -all > "$6_log.txt" &
 echo "Running: ${7#./}"
 recon-all -i "$7" -s "$7DIR" -all > "$7_log.txt" &
 echo "Running: ${8#./}"
 recon-all -i "$8" -s "$8DIR" -all > "$8_log.txt" &
 echo "Running: ${9#./}"
 recon-all -i "$9" -s "$9DIR" -all > "$9_log.txt"
 echo "Continuing to next batch"'
echo "Batch Completed!!!!!"

答案1

您的脚本不会一次运行所有文件,而会逐个运行。并且您在后台运行命令 recon-all,而不等待其响应,因此在下次运行中,它会选择下一个要运行的文件,并且仍然在后台运行。

使用findwithxargs后它将在前一个文件逐个完成后运行下一个文件。

find -type f -name '*.nil' -print0 |xargs -n1 -0 sh -c 'recon-all -i "$1" -s "$1DIR" -all > "$1_log3.txt"' sh

要分 10 批运行,请执行

find -type f -name '*.nil' -print0 |xargs -n10 -0 sh -c '
     recon-all -i "$1" -i "$2" -i "$3" -i "$4" -i "$5" -i "$6" -i "$7" -i "$8" -i "$9" -i "$10" -s "$1DIR" -all > "$1_log3.txt"' sh

请注意,-s主题取自上面的第一个文件名。

相关内容