[linux] 리눅스에서 디렉토리를 반복하는 방법?

Linux에서 bash로 스크립트를 작성 중이며 주어진 디렉토리의 모든 하위 디렉토리 이름을 거쳐야합니다. 이 디렉토리를 반복하고 정규 파일을 건너 뛰려면 어떻게해야합니까?

예를 들어
, 주어진 디렉토리는 /tmp/
다음과 같은 서브 디렉토리를 갖습니다./tmp/A, /tmp/B, /tmp/C

A, B, C를 검색하고 싶습니다.



답변

cd /tmp
find . -maxdepth 1 -mindepth 1 -type d -printf '%f\n'

간단한 설명 :

  • find 파일을 찾습니다 (분명히)

  • .is 다음에있는 현재 디렉토리 cd입니다 /tmp(IMHO /tmpfind명령에 직접 사용하는 것보다 융통성이 있습니다 . cd이 폴더에서 추가 조치를 수행하려는 경우 변경할 위치가 하나뿐입니다 ).

  • -maxdepth 1하고 -mindepth 1있는지 확인 find은 현재 디렉토리에있는 외모와 포함하지 않는 .결과 자체를

  • -type d 디렉토리 만 찾습니다

  • -printf '%f\n 각 적중에 대해 찾은 폴더 이름 (및 줄 바꾸기) 만 인쇄합니다.

vo!


답변

지금까지의 모든 대답은을 사용 find하므로 쉘 만있는 답변이 있습니다 . 귀하의 경우 외부 도구가 필요하지 않습니다.

for dir in /tmp/*/     # list directories in the form "/tmp/dirname/"
do
    dir=${dir%*/}      # remove the trailing "/"
    echo ${dir##*/}    # print everything after the final "/"
done


답변

숨겨진 디렉토리 (점으로 시작)를 포함한 모든 디렉토리를 다음과 같이 반복 할 수 있습니다.

for file in */ .*/ ; do echo "$file is a directory"; done

참고 : 폴더에 숨겨진 디렉토리가 하나 이상있는 경우에만 목록 사용이 */ .*/zsh에서 작동합니다. 배쉬에서는 또한 표시됩니다 ...


bash가 숨겨진 디렉토리를 포함하는 또 다른 가능성은 다음을 사용하는 것입니다.

shopt -s dotglob;
for file in */ ; do echo "$file is a directory"; done

심볼릭 링크를 제외하려면 다음을 수행하십시오.

for file in */ ; do
  if [[ -d "$file" && ! -L "$file" ]]; then
    echo "$file is a directory";
  fi;
done

각 솔루션에서 후행 디렉토리 이름 (질문에 따라 A, B, C) 만 출력하려면 루프 내에서 이것을 사용하십시오.

file="${file%/}"     # strip trailing slash
file="${file##*/}"   # strip path and leading slash
echo "$file is the directoryname without slashes"

예 (공백이 포함 된 디렉토리에서도 작동) :

mkdir /tmp/A /tmp/B /tmp/C "/tmp/ dir with spaces"
for file in /tmp/*/ ; do file="${file%/}"; echo "${file##*/}"; done


답변

공백이 포함 된 디렉토리에서 작동

Sorpigal에서 영감을 받음

while IFS= read -d $'\0' -r file ; do
    echo $file; ls $file ;
done < <(find /path/to/dir/ -mindepth 1 -maxdepth 1 -type d -print0)

원본 게시물 (공백과 함께 작동하지 않음)

Boldewyn에서 영감을 얻음 : find명령 이있는 루프의 예 .

for D in $(find /path/to/dir/ -mindepth 1 -maxdepth 1 -type d) ; do
    echo $D ;
done


답변

find . -mindepth 1 -maxdepth 1 -type d -printf "%P\n"


답변

내가 가장 자주 사용하는 기술은 find | xargs입니다. 예를 들어,이 디렉토리의 모든 파일과 모든 서브 디렉토리를 모두 읽을 수있게하려면 다음을 수행하십시오.

find . -type f -print0 | xargs -0 chmod go+r
find . -type d -print0 | xargs -0 chmod go+rx

-print0옵션은 공백 대신 NULL 문자로 종료됩니다. 이 -0옵션은 입력을 같은 방식으로 나눕니다. 공백이있는 파일에 사용하는 조합입니다.

이 명령 체인을 모든 라인 출력을 가져 와서 명령 find끝에 붙여서 그림으로 표시 할 수 있습니다 chmod.

명령이 끝이 아닌 중간에 인수로 실행하려면 약간 창의적이어야합니다. 예를 들어, 모든 하위 디렉토리로 변경하고 명령을 실행해야했습니다 latemk -c. 그래서 나는 ( Wikipedia에서 ) 사용했다 :

find . -type d -depth 1 -print0 | \
    xargs -0 sh -c 'for dir; do pushd "$dir" && latexmk -c && popd; done' fnord

이 효과는 for dir $(subdirs); do stuff; done있지만 이름에 공백이있는 디렉토리에는 안전합니다. 또한 별도의 호출 stuff이 동일한 쉘에서 이루어 지므로 내 명령에서을 사용하여 현재 디렉토리로 돌아 가야합니다 popd.


답변

빌드 할 수있는 최소 bash 루프 (ghostdog74 답변 기반)

for dir in directory/*
do
  echo ${dir}
done

디렉토리별로 전체 파일을 압축

for dir in directory/*
do
  zip -r ${dir##*/} ${dir}
done