다른 디렉토리에 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
파일당 하나씩 실행하지 마세요.
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
포함되지 않거나 /
문자로 끝나는 경우도 있습니다. ./