각 디렉터리로 이동하여 명령을 실행하는 방법은 무엇입니까?
parent_directory 내의 각 디렉토리를 통과하고 각 디렉토리에서 명령을 실행하는 bash 스크립트를 작성하려면 어떻게 해야 합니까?
디렉토리 구조는 다음과 같습니다.
parent_directory(이름은 무엇이든 될 수 있음 - 패턴을 따르지 않음)
- 001(디렉토리 이름은 이 패턴을 따릅니다)
- 0001.txt(파일 이름은 이 패턴을 따릅니다)
- 0002.txt
- 0003.txt
- 002
- 0001.txt
- 0002.txt
- 0003.txt
- 0004.txt
- 003
- 0001.txt
디렉터리 수를 알 수 없습니다.
find . -maxdepth 1 -type d \( ! -name . \) -exec bash -c "cd '{}' && pwd" \;
그\( ! -name . \)
현재 디렉터리에서 명령을 실행하지 않도록 합니다.
현재 디렉터리가 다음과 같을 때 다음을 수행할 수 있습니다.parent_directory
:
for d in [0-9][0-9][0-9]
do
( cd "$d" && your-command-here )
done
그(
그리고.)
기본 스크립트에서 현재 디렉토리가 변경되지 않도록 하위 셸을 만듭니다.
파이프를 사용하여 이를 달성할 수 있습니다.xargs
문제점은 당신이 그것을 사용해야 한다는 것입니다.-I
bash 명령의 하위 문자열을 각각이 전달하는 하위 문자열로 바꿀 플래그xargs
.
ls -d */ | xargs -I {} bash -c "cd '{}' && pwd"
교체할 수 있습니다.pwd
각 디렉토리에서 실행할 명령을 사용합니다.
GNU를 사용하는 경우find
해볼 수 있습니다-execdir
매개변수(예:
find . -type d -execdir realpath "{}" ';'
또는 (@gniourf_gniourf 주석에 따라):
find . -type d -execdir sh -c 'printf "%s/%s\n" "$PWD" "$0"' {} \;
참고: 사용할 수 있습니다.${0#./}
대신에$0
고쳐야 할./
맨 앞에
또는 보다 실질적인 예:
find . -name .git -type d -execdir git pull -v ';'
현재 디렉터리를 포함하려면 다음을 사용하는 것이 훨씬 더 간단합니다.-exec
:
find . -type d -exec sh -c 'cd -P -- "{}" && pwd -P' \;
또는 사용xargs
:
find . -type d -print0 | xargs -0 -L1 sh -c 'cd "$0" && pwd && echo Do stuff'
또는 @gniourf_gniourf에 의해 제안된 유사한 예:
find . -type d -print0 | while IFS= read -r -d '' file; do
# ...
done
위의 예는 이름에 공백이 있는 디렉토리를 지원합니다.
또는 bash 어레이에 할당함으로써:
dirs=($(find . -type d))
for dir in "${dirs[@]}"; do
cd "$dir"
echo $PWD
done
바꾸다.
특정 폴더 이름으로 이동합니다.재귀적으로 실행할 필요가 없는 경우 다음을 사용할 수 있습니다.dirs=(*)
대신.위의 예에서는 이름에 공백이 있는 디렉토리를 지원하지 않습니다.
따라서 @gniourf_gniourf가 제안한 것처럼 명시적 루프를 사용하지 않고 find의 출력을 배열에 넣을 수 있는 유일한 방법은 Bash 4.4에서 다음과 같습니다.
mapfile -t -d '' dirs < <(find . -type d -print0)
ls -d */ | awk '{print $NF}' | xargs -n1 sh -c 'cd $0 && pwd && echo Do stuff'
위의 예는 OP의 요청에 따라 현재 dir를 무시하지만 공백이 있는 이름에서는 중단됩니다.
참고 항목:
- Bash: SO의 각 디렉터리에 대해
- 현재 경로에 있는 모든 디렉터리를 입력하고 스크립트를 실행하는 방법은 무엇입니까?SE Ubuntu에서
최상위 폴더를 알고 있는 경우 다음과 같은 내용을 작성할 수 있습니다.
for dir in `ls $YOUR_TOP_LEVEL_FOLDER`;
do
for subdir in `ls $YOUR_TOP_LEVEL_FOLDER/$dir`;
do
$(PLAY AS MUCH AS YOU WANT);
done
done
$(PLAY ASMUSY YOURSELF)에서 원하는 만큼의 코드를 넣을 수 있습니다.
참고로 저는 어떤 디렉토리에서도 "cd"를 하지 않았습니다.
건배.
for dir in PARENT/*
do
test -d "$dir" || continue
# Do something with $dir...
done
하나의 라이너는 빠르고 더러운 사용에 좋지만, 스크립트 작성을 위해 아래의 더 자세한 버전을 선호합니다.이것은 많은 에지 케이스를 처리하고 폴더에서 실행할 더 복잡한 코드를 작성할 수 있게 해주는 제가 사용하는 템플릿입니다.bash 코드는 function dir_command에 기록할 수 있습니다.아래에서 dir_coomand는 각 리포지토리 git에 태그를 지정하여 예제로 구현합니다.나머지 스크립트에서는 디렉터리의 각 폴더에 대해 dir_command를 호출합니다.주어진 폴더 집합을 통해서만 반복하는 예도 포함됩니다.
#!/bin/bash
#Use set -x if you want to echo each command while getting executed
#set -x
#Save current directory so we can restore it later
cur=$PWD
#Save command line arguments so functions can access it
args=("$@")
#Put your code in this function
#To access command line arguments use syntax ${args[1]} etc
function dir_command {
#This example command implements doing git status for folder
cd $1
echo "$(tput setaf 2)$1$(tput sgr 0)"
git tag -a ${args[0]} -m "${args[1]}"
git push --tags
cd ..
}
#This loop will go to each immediate child and execute dir_command
find . -maxdepth 1 -type d \( ! -name . \) | while read dir; do
dir_command "$dir/"
done
#This example loop only loops through give set of folders
declare -a dirs=("dir1" "dir2" "dir3")
for dir in "${dirs[@]}"; do
dir_command "$dir/"
done
#Restore the folder
cd "$cur"
폴더를 통해서만 반복하기를 원하기 때문에 파일 형식에 대한 요점을 모르겠습니다.당신은 이런 것을 찾고 있습니까?
cd parent
find . -type d | while read d; do
ls $d/
done
사용할 수 있습니다.
find .
현재 디렉터리에 있는 모든 파일/파일을 반복적으로 검색합니다.
당신은 xargs 명령어의 출력을 파이프로 연결할 수 있습니다.
find . | xargs 'command here'
#!/bin.bash
for folder_to_go in $(find . -mindepth 1 -maxdepth 1 -type d \( -name "*" \) ) ;
# you can add pattern insted of * , here it goes to any folder
#-mindepth / maxdepth 1 means one folder depth
do
cd $folder_to_go
echo $folder_to_go "########################################## "
whatever you want to do is here
cd ../ # if maxdepth/mindepath = 2, cd ../../
done
#you can try adding many internal for loops with many patterns, this will sneak anywhere you want
다음과 같이 각 폴더에서 명령 시퀀스를 한 줄로 실행할 수 있습니다.
for d in PARENT_FOLDER/*; do (cd "$d" && tar -cvzf $d.tar.gz *.*)); done
for p in [0-9][0-9][0-9];do
(
cd $p
for f in [0-9][0-9][0-9][0-9]*.txt;do
ls $f; # Your operands
done
)
done
언급URL : https://stackoverflow.com/questions/7470165/how-to-go-to-each-directory-and-execute-a-command
'programing' 카테고리의 다른 글
Postgre를 시작하는 방법윈도우즈의 SQL? (0) | 2023.05.17 |
---|---|
PSQL 예외: 현재 트랜잭션이 중단되었습니다. 트랜잭션 블록이 끝날 때까지 명령이 무시됩니다. (0) | 2023.05.12 |
Angular/Angular Material에서 매트 수평 스텝의 스텝을 프로그래밍 방식으로 이동할 수 있습니까? (0) | 2023.05.12 |
스토리보드에서 선택한 탭 모음 항목의 색상 변경 (0) | 2023.05.12 |
wpf 대화 상자에서 기본 버튼을 선택하는 방법은 무엇입니까? (0) | 2023.05.12 |