for 루프에서는 변수가 증가하지 않습니다.

for 루프에서는 변수가 증가하지 않습니다.

작업 디렉토리의 디렉토리 수를 인쇄하려고 합니다. 어떤 이유로 내 카운터가 증가하지 않습니다. 왠지 말해줘?

#!/bin/bash
n=0
for afile in $(ls)
do
    if [ -d $afile ]
    then
      (( n ++ ))
    fi
done
echo There are $n directories under the current directory $(pwd).
exit 0

이상하게도 이 프로그램은 ls .. (up 디렉토리)를 통해 반복되는 것 같습니다.

for myfile in $(ls ..)
do
    if [ -d "../$myfile" ]
    then
      echo "../$myfile (dir)"
    else
      echo ../$myfile
    fi
done
exit 0

답변1

(현재 디렉토리에서) 숨겨지지 않은 디렉토리의 수를 계산하려면 다음을 사용하십시오 bash.

shopt -s nullglob
set -- */
printf 'There are %d non-hidden subdirectories in %s\n' "$#" "$PWD"

숨겨진 디렉터리 수를 포함하려면:

shopt -s dotglob nullglob
set -- */
printf 'There are %d subdirectories in %s\n' "$#" "$PWD"

이 코드의 목적은 스키마를 확장 */하고 스키마가 확장된 후 이름 수를 계산하는 것입니다. 이 패턴은 슬래시로 끝나기 때문에오직디렉토리 이름(또는 디렉토리에 대한 기호 링크 이름)으로 확장됩니다.

디렉토리 이름은 위치 인수 등에 할당되며 $1이러한 인수의 수는 쉘에 의해 유지됩니다(따라서 계산하기 위해 실제로 루프를 돌릴 필요가 없습니다).$2set$#

bash배열이 더 편하다고 생각 된다면 다음을 수행하세요.

shopt -s dotglob nullglob
dirs=( */ )
printf 'There are %d subdirectories in %s\n' "${#dirs[@]}" "$PWD"

이는 위치 매개변수 대신 명명된 배열을 사용한다는 점을 제외하면 본질적으로 동일합니다.

dotglob의 쉘 옵션은 숨겨진 이름과 숨겨지지 않은 이름 bash모두와 일치 합니다. *nullglob옵션을 사용하면 일치하지 않는 패턴이 아무것도 확장되지 않습니다.

관련된:

답변2

귀하의 코드는 제게는 잘 작동하지만 일부 버그가 있어서 어떤 경우에는 실패합니다(예: 파일 이름에 공백이 포함된 경우).

  • 우선 하지 마세요.ls를 구문 분석하다. 대신 반복을 위해 glob을 사용하세요. 즉 , $(ls).*
  • 변수를 읽을 때 따옴표로 묶어야 합니다. 즉, "$foo"대신 을 사용하십시오 $foo. 인용하지 않으면 쉘은 출력을 IFS(예: 공백)로 분할합니다. 스크립트를 사용하여 이를 테스트할 수 있습니다. 공백 없이 일부 디렉터리를 포함하고 공백으로 테스트합니다. 전자만 계산됩니다.

고정된 코드는 다음과 같습니다.

#!/bin/bash
n=0
for afile in *
do
    if [ -d "$afile" ]
    then
      (( n ++ ))
    fi
done
echo There are $n directories under the current directory $(pwd).
exit 0

이것이 명백한지 확실하지 않지만 스크립트는 현재 디렉터리에서 실행됩니다.

관련 정보