「インクルードフォルダ内の複数のサブディレクトリにあるファイルに対してコマンドを実行する」(例:ファイルを含む各サブディレクトリにCDを移動してコマンドを実行するなど)

「インクルードフォルダ内の複数のサブディレクトリにあるファイルに対してコマンドを実行する」(例:ファイルを含む各サブディレクトリに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 

これはうまくいきません。ここで助けを得ることを期待しています。してください。

答え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$fead h(ディレクトリ名)と対応する$f:tail t(デフォルト名)に展開されます。


たとえば、ディレクトリ名が改行文字で終わっても、まだ機能します。dirname(またはzsh's $var:h)を使用するとより良い結果が得られますが、インポートパスに文字がdirname含まれていないか、/文字で終わる場合があります。 。/

関連情報