작업 디렉토리의 디렉토리 수를 인쇄하려고 합니다. 어떤 이유로 내 카운터가 증가하지 않습니다. 왠지 말해줘?
#!/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
이러한 인수의 수는 쉘에 의해 유지됩니다(따라서 계산하기 위해 실제로 루프를 돌릴 필요가 없습니다).$2
set
$#
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
이것이 명백한지 확실하지 않지만 스크립트는 현재 디렉터리에서 실행됩니다.