Bash에서 폴더 식별

Bash에서 폴더 식별

기본 수준 폴더 내의 폴더만 식별하는 방법을 배우려고 합니다. 예:

  • 기본
  • -폴더 1
  • -폴더 2
  • -폴더 3

다음 스크립트로 시작합니다.

#!/bin/bash

LOCATION="/mnt/test/build/"

for folder in $(ls $LOCATION); do

    echo "$folder"
done

그러나 스크립트를 실행하면 전체 내용이 에코되고 폴더 내에 공백이 있으면 두 줄에 이름이 추가됩니다. 에코 라인을 에서 "$folder"로 변경하면 '$folder'해당 폴더만 에코됩니다. 암시적인 기사도 좋습니다.

답변1

ls단순히 디렉토리의 내용을 반복하는 대신 글로빙을 사용하십시오 .

#!/bin/bash
LOCATION="/mnt/test/build/"
for folder in "$LOCATION"/*; do
    [ -d "$folder" ] || continue
    echo "$folder"
done

[ -d "$folder" ]명령은 $folder디렉터리인지 여부를 테스트합니다. 그렇지 않은 경우 해당 항목을 건너뜁니다 continue. $LOCATION및 주변의 따옴표에 유의하세요 $folder. 공백이 포함된 경우 스크립트가 $LOCATION중단되는 것을 방지합니다.

정말로 처리할 것이 필요한 경우 ls다음과 같이 사용하십시오.

ls "$LOCATION" | while read folder; do
    echo "$folder"
done

루프 이후 루프 내부의 변수에 액세스해야 한다는 추가적인 제한이 있는 경우 Bash 프로세스 대체를 사용하십시오.

while read folder; do
    echo "$folder"
done < <(ls "$LOCATION")

Bash 매뉴얼은 다음 위치에 있습니다.http://www.gnu.org/software/bash/manual/.

답변2

출력을 구문 분석하지 않습니다.ls. ls디렉토리의 내용을 나열할 필요는 없습니다 . 쉘 와일드카드를 사용할 수 있습니다.

을 작성하면 $(ls $LOCATION)명령의 출력은 ls공백이 포함된 별도의 단어로 분할됩니다. 이것이 바로 귀하의 명령이 파일 이름을 공백으로 뒤섞은 이유입니다. 공백이 구분 기호로 표시되지 않도록 해당 변수를 수정할 수 있지만 IFS파일 이름을 구분하는 데 사용되는 줄 바꿈과 파일 이름 내의 줄 바꿈을 구별할 수 있는 방법이 없으므로 문제를 완전히 피할 수는 없습니다. 또한 분할로 인해 생성된 각 단어는 glob(즉, 와일드카드 패턴)으로 처리되고 일치하는 파일 목록(있는 경우)으로 대체됩니다. 쉘 스크립팅의 간단한 규칙은 다음과 같습니다."$foo"변수 대체 및 명령 대체에는 항상 큰따옴표를 사용하세요."$(foo)". 큰따옴표는 분할과 와일드카드를 방지합니다.

다음 코드 조각은 파일 이름을 변경하지 않고 각 파일의 전체 경로를 인쇄한다는 점을 제외하면 루프와 동일합니다.

for x in "$LOCATION"/*; do
  echo "$x"
done

상대 경로를 원하는 경우 $LOCATION한 가지 방법은 먼저 대상 디렉터리로 변경하는 것입니다.

cd "$LOCATION"
for x in *; do
  echo "$x"
done

또 다른 방법은 파일 이름에서 접두사를 제거하는 것입니다.

for full_path in "$LOCATION"/*; do
  relative_name=${full_path#"$LOCATION/"}
  echo "$relative_name"
done

그러면 대상 디렉터리에 있는 모든 파일의 이름이 인쇄됩니다. 하위 디렉터리(디렉토리에 대한 심볼릭 링크 포함)만 나열하려면 /glob 패턴에 를 추가하여 일치 항목을 제한하세요.

for full_path in "$LOCATION"/*/; do
  relative_name=${full_path#"$LOCATION/"}
  relative_name=${relative_name%/}
  echo "$relative_name"
done

심볼릭 링크를 포함하지 않으려면 루프 내부의 디렉터리에 대해 명시적인 테스트를 수행하세요.

for full_path in "$LOCATION"/*/; do
  if ! [ -d "$full_path" ]; then continue; fi
  relative_name=${full_path#"$LOCATION/"}
  relative_name=${relative_name%/}
  echo "$relative_name"
done

답변3

귀하의 레벨 아래에 있는 모든 디렉토리를 찾으십시오.

find . -type d

자신을 한 수준으로 제한하고 싶다면

find . -type d -maxdepth 1 -mindepth 1

편집하다

귀하의 질문 중 일부를 놓쳤습니다.

SAVEIFS=$IFS
IFS=$(echo -en "\n\b")
for dir in $( find . -type d -maxdepth 1 -mindepth 1 ) ; do
  echo ${dir}
done
IFS=$SAVEIFS

그러나 수행하려는 작업에 따라 -execfind 옵션을 사용하여 각 파일에 대해 명령을 실행할 수도 있습니다.

답변4

이 명령은 $LOCATION에서 직접 모든 디렉터리만 찾습니다. 해당 디렉토리의 내용은 나열되지 않습니다.

#!/bin/bash
LOCATION="/mnt/test/build/"

find "$LOCATION" -mindepth 1 -maxdepth 1 -type d

절대 경로 대신 상대 경로만 인쇄하려면 다음 명령을 사용하십시오.

find "$LOCATION" -mindepth 1 -maxdepth 1 -type d -printf "%f\n"

관련 정보