別のディレクトリに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
重複しています。除外されますが、.
とにかくandによって除外されます.
。-type f
-name filename.sh
-execdir
(BSDでは)は標準述語ではありませんが、サポートしているfind
場合はサポートできます(GNUでは非標準ですが)。find
-mindepth
-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
ファイルごとに1つずつ実行しないでください。
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
$f:h
$f
ead h
(ディレクトリ名)と対応する$f:t
ail t
(デフォルト名)に展開されます。
たとえば、ディレクトリ名が改行文字で終わっても、まだ機能します。dirname
(またはzsh
's $var:h
)を使用するとより良い結果が得られますが、インポートパスに文字がdirname
含まれていないか、/
文字で終わる場合があります。 。/