루프를 사용하여 수행하고 싶습니다 for
. 이것이 내가 지금까지 생각한 것이지만 작동하지 않습니다.
for home in /home/ {.,/}*; do echo "$home"; done
가능하다면 비재귀적으로 이 작업을 수행하고 싶습니다.
답변1
for 는 find
현재 디렉터리의 디렉터리 유형이 아니므로 재귀가 필요하지 않습니다.
find . ! -name . -prune ! -type d | grep -c /
...디렉토리에 대해서만 두 번째 폭발을 제거하거나 -type
모든 파일 형식에 대한 테스트를 완전히 제거하십시오.
이 경우 재귀가 없으면 파일당 하나의 경로 구분 기호만 표시되므로 계산할 항목과 계산할 위치에 대해 혼동이 없기 때문에 쉽습니다. 파일 수를 계산해야 할 때 개행 문자를 계산하면 문제가 발생할 수 있습니다. 두 가지 사항은 서로 관련이 없습니다. 그렇다면 또 무엇을 할 수 있습니까?
find .//. | grep -c '^\.//\.'
...자식 개체의 정확한 수와 현재 디렉터리에 루트가 있는 개체를 반환합니다.
또한 작동하지만 반대 논리를 사용합니다. 내부적으로 줄 바꿈을 인용하고 stat()
각 구성 파일 대신 각 디렉터리만 필요하기 때문에 아마도 더 빠를 것입니다.
\ls -1qRA . | grep -Exc \[^/]+
-R
이 옵션을 폐기하면 ls
재귀 없이도 작동합니다.
그러나 위의 내용은 파일 이름의 멀티바이트 문자와 호환되지 않는 로케일에 따라 잘못된 개수를 반환할 수 있습니다. LC_ALL=C
POSIX 호환 환경에 배치하면 ls
이러한 일이 발생하지 않으며 상당히 큰 트리의 깊이 수를 사용하면 결국 성능에만 도움이 될 수 있습니다.
답변2
원하는 작업을 거의 수행할 수 있는 더 높은 수준의 명령이 많이 있지만 이는 쉘 스크립트에서 동일한 작업을 수행하는 방법을 보여주는 좋은 예입니다. 이것은 작동해야합니다어느시스템은 /bin/sh
다른 명령에 의존하지 않습니다.
이 스크립트를 임의의 파일 이름과 유형으로 저장하여 sh ./whatever_you_named_it
실행할 수 있습니다.
두 부분으로 나누었는데,파일 나열, 그리고파일 개수 계산. 파일을 재귀적으로 나열하는 것은 가장 복잡하지만 목록이 있으면 쉽게 셀 수 있습니다.
파일 나열
이 스크립트는 홈 디렉터리 또는 인수로 받는 디렉터리 아래의 모든 파일과 디렉터리를 반복적으로 나열합니다. 매개변수가 없으면 기본값은 홈 디렉터리입니다.
#!/bin/sh
if test $# -eq 0
then
startdir="$HOME"
else
startdir="$1"
fi
for f in "$start"/* # step through all files in the starting directory
do
echo "$f" # print the file name
if test -d "$f" # is the file a directory? (-d)
then
sh "$0" "$f" # yes call this script with the dir as arg
fi
done
각 단계에 대해 논의해 보겠습니다.
인수가 스크립트에 전달되지 않으면 "$HOME"이 시작 디렉터리로 사용되고, 그렇지 않으면 첫 번째 인수가 사용됩니다. ($#에는 스크립트에 전달된 인수의 개수가 포함되어 있으며,
test
0인지 확인하기 위해 셸의 내장 명령을 사용합니다 ):if test $# -eq 0 then startdir="$HOME" else startdir="$1" fi
홈 디렉터리의 파일을 반복합니다.
"$HOME"/*
홈 디렉터리의 최상위 수준에서 숨겨지지 않은 모든 파일과 디렉터리로 확장합니다.for f in "$HOME"/* do
파일 이름을 인쇄합니다. 나는 당신이 알고 있다고 생각합니다
echo
:echo "$f" # print the file name
options 을 사용하여 셸 내장
test
명령을 호출합니다-d
.test
인수가"$f"
디렉터리이면 true를 반환합니다. 이는 일반적[ -d "$f" ]
으로 간결하게 작성되지만 실제로는 명령입니다. ["test expr"에 대한 매뉴얼 페이지 검색sh
]:if test -d "$f" # is the file a directory? (-d) then
다음 진술은 우리가 반복하는 곳입니다. 현재 실행 중인 스크립트의 새 복사본을 시작하고 여기에 현재 "$f" 디렉터리 이름을 전달합니다.
$0
현재 쉘 스크립트의 파일 이름으로 확장됩니다 . 여기에 파일 이름을 입력하는 대신$0
이름이 변경되더라도 스크립트가 작동하도록 하는 방식입니다. 예를 들어 스크립트가 호출되면rlist
작성할 수도 있지만sh rlist "$f"
스크립트 이름이 바뀌면 존재하지 않는 스크립트 또는 잘못된 스크립트를 호출하기 때문에 스크립트가 더 이상 올바르게 실행되지 않습니다. [맨 페이지의 "특수 매개변수" 참조sh
]:sh "$0" "$f" # yes call this script with the dir as arg
if
명령문과 루프를 종료합니다for
.fi done
파일 개수 계산
지금까지 스크립트는 파일을 나열하지만 계산하지는 않습니다. 모든 파일과 디렉터리의 수를 얻으려면 다음 명령을 실행하십시오.
sh ./scriptname | wc -l
wc -l
"단어 개수" 명령이며 -l
이 옵션이 있는 줄만 계산합니다. 위의 파이프는 홈 디렉터리에 있는 파일 수인 숫자를 인쇄합니다.
답변3
사용찾다:
비재귀적이라는 것은 하위 디렉터리가 아닌 /home의 파일/디렉터리 수만 원한다는 뜻입니까? 이 경우 이 옵션을 사용하여 결과를 최상위 수준으로 제한할 수 있습니다 maxdepth
.
find /home -maxdepth 1 | wc -l
사용:
i=0; for home in ~/*; do (( i++ )); done; echo $i
이중 괄호와 주변 i++ 사이의 공백에 유의하세요.