我在不同的目录中有一个名为 filename.sh 的文件。我正在尝试同时提交此文件以在多个集群节点上运行。我需要找到这个文件,无论它们在哪里,cd到其包含的文件夹中并执行命令“sbatch run_code.sh”这是我尝试过的。
find . -mindepth 1 -type f -name filename.sh -exec sbatch run_code.sh {} \;
它可以工作,只是它从当前文件夹运行命令,该文件夹不包含运行代码所需的依赖项。
或者我倾向于这样的 for 循环
for d in dirname; do
cd "$(dirname "$(find . -type f -name filename.sh)")" && sbatch run_code.sh)
done
这是行不通的。我期待在这里得到一些帮助。请。
答案1
听起来像你想要的:
find . -name filename.sh -type f -execdir sbatch run_code.sh {} ';'
-mindepth 1
是多余的。它排除.
,但无论如何都被和.
排除。-type f
-name filename.sh
-execdir
(来自 BSD),不是一个标准find
谓词,但是如果你find
支持-mindepth
(虽然来自 GNU 也是非标准),它也可能支持-execdir
.
-execdir
正是为此。它就像-exec
只是在所选文件的父目录中运行命令。在这里,根据find
实现的不同,正在运行的命令将是sbatch run_code.sh ./filename.sh
或sbatch run_code.sh filename.sh
。{}
如果您不希望将filename.sh
作为参数传递给命令,请删除。
对于find
不支持的实现-execdir
,您可以这样做:
find . -name filename.sh -type f -exec sh -c '
cd "${1%/*}" && exec sbatch run_code.sh "${1##*/}"' sh {} ';'
${1%/*}
但删除了$1
最短的尾部匹配/*
,因此它的行为就像"$(dirname -- "$1")"
但更高效、更可靠。${1##*/}
删除最长的头部匹配,*/
给你一个basename
类似的结果。
或者避免sh
每个文件运行一个:
find . -name filename.sh -type f -exec sh -c '
for file do
(cd "${file%/*}" && exec sbatch run_code.sh "${file##*/}"
done' sh {} +
使用zsh
shell,您还可以执行以下操作:
for f (./**/filename.sh(ND.)) (cd $f:h && sbatch run_code.sh $f:t)
(exec
(保存进程)不是必需的,因为zsh
它已经隐式地用于子 shell 中运行的最后一个命令)。
$f:h
扩展为$f
的h
ead (目录名)及其$f:t
ail t
(基本名)。
例如,如果目录名称以换行符结尾,则 仍然有效;在某些情况下,使用dirname
(or zsh
's $var:h
) 会给出更好的结果,但当获取 of 的路径dirname
不包含任何或以字符/
结尾时。/