디렉토리에 얼마나 많은 파일이나 디렉토리가 있는지 wc
계산하기 위해 단어 카운터( )와 파이프를 사용하는 방법은 무엇입니까 ?/usr/bin
답변1
ls
이를 수행하는 한 가지 방법은 파일 목록을 제공하는 것을 사용하는 것이지만 , 목록에는 한 줄에 하나의 파일이나 디렉터리만 표시되도록 하고 싶습니다. 스위치가 -1
우리를 위해 이 일을 해줄 것입니다.
$ ls -1
dir1
dir2
dir3
fileA
fileB
fileC
예
빈 디렉터리에 위의 샘플 데이터를 만듭니다.
$ mkdir dir{1..3}
$ touch file{A..C}
확인하다:
$ ls
dir1 dir2 dir3 fileA fileB fileC
wc -l
이제 계산하려면 출력에서 파일 또는 디렉터리에 해당하는 줄 수 계산을 사용할 수 있습니다 ls -1
.
$ ls -1 | wc -l
6
(단, 숨김 파일은 포함되지 않으니 주의하세요)
파일이나 디렉터리의 수를 세되 함께 세지는 않습니다.
파일이나 디렉터리의 수를 계산하려면 전략을 약간 변경해야 합니다. 이 경우 ls -l
디렉토리가 무엇인지, aa 파일이 무엇인지 보여주기 때문에 이를 사용하겠습니다.
예
$ ls -l
total 12
drwxrwxr-x 2 saml saml 4096 Nov 16 09:48 dir1
drwxrwxr-x 2 saml saml 4096 Nov 16 09:48 dir2
drwxrwxr-x 2 saml saml 4096 Nov 16 09:48 dir3
-rw-rw-r-- 1 saml saml 0 Nov 16 09:49 fileA
-rw-rw-r-- 1 saml saml 0 Nov 16 09:49 fileB
-rw-rw-r-- 1 saml saml 0 Nov 16 09:49 fileC
grep
그런 다음 다음을 사용하여 디렉터리 또는 디렉터리가 아닌 항목을 필터링 할 수 있습니다 .
# directories
$ ls -l | grep "^d"
drwxrwxr-x 2 saml saml 4096 Nov 16 09:48 dir1
drwxrwxr-x 2 saml saml 4096 Nov 16 09:48 dir2
drwxrwxr-x 2 saml saml 4096 Nov 16 09:48 dir3
# regular files
$ ls -l | grep "^-"
-rw-rw-r-- 1 saml saml 0 Nov 16 09:49 fileA
-rw-rw-r-- 1 saml saml 0 Nov 16 09:49 fileB
-rw-rw-r-- 1 saml saml 0 Nov 16 09:49 fileC
이제 wc -l
위의 계산을 다시 사용하십시오.
# directories
$ ls -l | grep "^d" | wc -l
3
# regular files
$ ls -l | grep "^-" | wc -l
3
그러나 wc
이를 완전히 피하고 다음 옵션을 사용할 grep
수 있습니다 -c
.
$ ls -l | grep -c '^d'
(다시 말하지만 숨겨진 파일은 포함되지 않습니다. 디렉터리와 일반 파일은 두 가지 유형의 파일입니다. 명명된 파이프, 심볼릭 링크, 장치, 소켓 등 더 많은 유형의 파일이 있습니다.)
재귀
파일과 디렉터리를 반복적으로 찾아야 하는 경우 /usr/bin
전략을 완전히 변경하고 이라는 다른 전략을 사용해야 할 수도 있습니다 find
.
예
$ find /usr/bin | wc -l
4632
(위 내용 /usr/bin
자체도 집계에 포함되지만)
위에서 사용한 동일한 기술을 사용하여 ls
유사한 작업을 수행 할 수 있지만 ls
일반적으로 출력을 구문 분석하는 데 좋은 도구는 아닙니다. find
다른 쪽은 이를 위해 만들어졌으며 파일이나 디렉터리를 찾기 위한 스위치를 제공합니다.
# find files
$ find /usr/bin -type f
# find directories
$ find /usr/bin -type d
(이번에는 find
숨겨진 파일이 포함됩니다( .
및 제외 ..
).
개행?
파일 이름이나 디렉토리 이름을 만들 때 줄 바꿈이 왜 합법적인 문자인지 이해하지 못했습니다. 따라서 위에서 설명한 방법을 사용 wc
하면 ls
이러한 방법과 충돌하지 않으므로 사용 시 이 점을 염두에 두시기 바랍니다.
예
줄 바꿈을 사용하여 디렉터리 및 파일 이름을 만듭니다.
$ mkdir $'dir4\n5'
$ touch $'fileD\nE'
ls
올바르게 표시하십시오.
$ ls -1
dir1
dir2
dir3
dir4?5
fileA
fileB
fileC
fileD?E
그러나 wc
개행 문자가 포함된 디렉터리와 파일은 1개 항목이 아닌 2개 항목으로 계산됩니다.
$ ls -1 | wc -l
10
GNU 구현을 사용하는 경우 이 문제를 해결하는 한 가지 방법 find
은 함수를 사용하여 find
찾은 각 파일에 대해 다른 것을 인쇄한 다음 해당 파일의 수를 계산하는 것입니다.
예
$ find . -printf . | wc -c
9
여기에서는 현재 디렉토리의 모든 항목( 제외 ..
)을 찾고 각각에 대해 점( )을 인쇄한 다음 줄 대신 바이트 수를 계산하는 기능을 .
사용하여 점 수를 계산합니다 .wc
wc -c
인용하다
답변2
GNU를 사용하여 디렉토리에 있는 각 유형의 파일 수를 재귀적으로 분석하려면 find
다음을 수행할 수 있습니다.
find /some/dir/. ! -name . -printf '%y\n' | sort | uniq -c | sed '
s/f/regular files/;t
s/d/directories/;t
s/l/symbolic links/;t
s/s/Unix domain sockets/;t
s/b/block devices/;t
s/c/character devices/;t
s/p/FIFOs/;t
s/D/Doors/;t
s/n/network special files/;t
s/.$/others (&)/'
/usr/bin
내 시스템 에서는 다음을 제공합니다.
3727 regular files
710 symbolic links
존재하다 /dev
:
83 block devices
203 character devices
31 directories
426 symbolic links
1 FIFOs
1 Unix domain sockets
심볼릭 링크의 경우 심볼릭 링크가 가리키는 파일 유형으로 계산되도록 하려면 symbolic links
다음과 같이 변경할 수 있습니다.
find /some/dir/. ! -name . -printf '%Y\n' | sort | uniq -c | sed '
s/f/regular files/;t
s/d/directories/;t
s/N/broken symbolic links/;t
s/s/Unix domain sockets/;t
s/b/block devices/;t
s/c/character devices/;t
s/p/FIFOs/;t
s/D/Doors/;t
s/n/network special files/;t
s/.$/others (&)/'
이제 이것은 나에게 다음을 제공합니다 /usr/bin
.
1 directories
4434 regular files
2 broken symbolic links
(깨진 심볼릭 링크는 find
파일이 존재하지 않거나, 액세스할 수 없는 디렉토리에 있거나, 파일 경로 확인에 주기가 있기 때문에 유형을 확인할 수 없는 파일을 가리키는 심볼릭 링크입니다. 제 경우에는 다음과 같습니다. 이제 두 개의 심볼릭 링크가 사라졌습니다.)
이 중 어느 것도 .
평화로 간주되지 않습니다 ..
. 이를 포함하고 싶다면(그 이유는 무엇입니까?) find
각 디렉토리에 대해 존재한다고 가정하고 체계적으로 계산하는 것 외에는 다른 방법이 없습니다.
find /some/dir/. -printf '%y\n' \( -name . -printf 'd\n' -o \
-type d -printf 'd\nd\n' \) | sort | uniq -c | sed '
s/f/regular files/;t
s/d/directories/;t
s/l/symbolic links/;t
s/s/Unix domain sockets/;t
s/b/block devices/;t
s/c/character devices/;t
s/p/FIFOs/;t
s/D/Doors/;t
s/n/network special files/;t
s/.$/others (&)/'
그런 다음 내 것이 주어졌습니다 /usr/bin
.
2 directories
3727 regular files
710 symbolic links
GNU에 접근할 수 없다면 find
첫 번째 것을 다음과 같이 다시 작성할 수 있습니다:
find /some/dir/. ! -name . \( \
-type f -exec printf '%.0sregular files\n' {} + -o \
-type d -exec printf '%.0sdirectories\n' {} + -o \
-type l -exec printf '%.0ssymbolic links\n' {} + -o \
-type s -exec printf '%.0sUnix domain sockets\n' {} + -o \
-type b -exec printf '%.0sblock devices\n' {} + -o \
-type c -exec printf '%.0scharacter devices\n' {} + -o \
-type p -exec printf '%.0sFIFOs\n' {} + -o \
-exec printf '%.0sothers\n' {} + \) | sort | uniq -c
엄밀히 말하면 우리는 계산하지 않았습니다.문서하지만디렉토리 항목. 비슷한 디렉터리에는 /usr/bin
동일한 파일을 가리키는 여러 항목이 있는 경우가 많습니다. 예를 들어, 여기에 있습니다:
$ ls -lid /usr/bin/{nvi,nview,nex}
672252 -rwxr-xr-x 3 root root 434616 May 25 07:40 /usr/bin/nex
672252 -rwxr-xr-x 3 root root 434616 May 25 07:40 /usr/bin/nvi
672252 -rwxr-xr-x 3 root root 434616 May 25 07:40 /usr/bin/nview
이는 동일한 파일(inode 672252가 있는 파일)에 대한 3개의 디렉토리 항목(파일 이름, 하드 링크라고도 함)입니다. GNU find
및 GNU를 사용하여 디렉터리 항목 대신 파일 수를 계산합니다 ( uniq
어쨌든 다른 디렉터리에 대한 하드 링크인 .
파일은 무시 ..
).
find /some/dir/. ! -name . -printf '%y\t%D:%i\n' |
sort -u |
cut -f1 |
uniq -c |
sed '
s/f/regular files/;t
s/d/directories/;t
s/l/symbolic links/;t
s/s/Unix domain sockets/;t
s/b/block devices/;t
s/c/character devices/;t
s/p/FIFOs/;t
s/d/Doors/;t
s/n/network special files/;t
s/.$/others (&)/'
광산에서는 /usr/bin
다음을 제공합니다.
3711 regular files
710 symbolic links
답변3
/usr/bin 아래의 모든 파일을 재귀적으로 원하는지 아니면 첫 번째 수준만 원하는지 말하지 않았습니다. 또한, 셀 수 있는 단어를 어떻게 얻나요? 그것을 찾는 일반적인 방법은 wc에서 find를 실행하는 것입니다. 다음과 같습니다: Find /usr/bin | wc -l Find는 거기에 있는 모든 것, 디렉토리 및 파일을 나열합니다. Wc -l은 find 출력의 모든 행 수를 계산합니다. 이게 수업 과제인가요? 그렇다면 괜찮습니다. 하지만 답변을 더 신중하게 맞춤화할 수 있도록 이 정보가 필요한 이유를 알고 싶습니다. 더 필요하시면 알려주세요. 코스타
답변4
Bash에서는 외부 도구가 필요하지 않습니다.
cd dir/ || exit; shopt -s nullglob; shopt -s dotglob; count=(*); echo "${#count}"
Bash에서는 외부 도구와 재귀가 필요하지 않습니다.
shopt -s globstar; shopt -s dotglob
for dir in **/*/; do
unset d f
for files in "$dir"*; do
[[ -f $files ]] && ((++f))
[[ -d $files ]] && ((++d))
done;
printf '%s\n' "$dir - files: ${f:-0} - directories: ${d:-0}"
done