如何“在包含文件夾內的多個子目錄中的文件上執行命令”,即 cd 到包含文件的每個子目錄並執行命令
我在不同的目錄中有一個名為 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
這是行不通的。我期待在這裡得到一些幫助。請。
聽起來像你想要的:
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
外殼,您還可以執行以下操作:for f (./**/filename.sh(ND.)) (cd $f:h && sbatch run_code.sh $f:t)
(
exec
(保存程序)不是必需的,因為zsh
它已經隱式地用於子shell中執行的最後一個命令)。
$f:h
擴展到$f
’sh
ead (dirname) 和$f:t
它的t
ail (basename)。例如,如果目錄名稱以換行符結尾,¹ 仍然可以工作;在某些情況下,使用
dirname
(或zsh
’s$var:h
)會產生更好的結果,儘管當獲取dirname
of 的路徑沒有任何字元/
或以/
字元結尾時。