단어 카운터 ( wc
) 및 파이핑을 사용하여 /usr/bin
디렉토리 에있는 파일 또는 디렉토리 수를 계산할 수 있습니까?
단어 카운터 ( wc
) 및 파이핑을 사용하여 /usr/bin
디렉토리 에있는 파일 또는 디렉토리 수를 계산할 수 있습니까?
답변:
한 가지 방법은 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
디렉토리가 무엇인지, 파일이 무엇인지 보여주기 때문에 사용 합니다.
$ 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
개행을 포함하는 디렉토리 및 파일은 하나가 아닌 2 개의 항목으로 계산됩니다.
$ ls -1 | wc -l
10
GNU 구현을 사용하는 경우이 문제를 해결하는 한 가지 방법 find
은 find
찾은 각 파일 대신 다른 것을 인쇄 한 다음 대신 그 수를 세는 기능을 사용하는 것입니다.
$ find . -printf . | wc -c
9
여기서는 현재 디렉토리에서 모든 것을 찾고 (을 제외하고 ..
) .
각각에 대해 점 ( )을 인쇄 한 다음 wc
줄 대신 바이트를 계산하는 능력을 사용하여 점을 계산합니다 wc -c
.
/usr/bin
이 모두 잘 지정되고 (공백이 포함되어 있지 않으므로 기술적으로도 가능할 수 있지만 echo * | wc -w
) 개행 문자가 포함 된 파일 이름에서 이러한 파일이 모두 손상 될 수 있습니다.
ls -l
않거나 ls -1
b / c를 깨뜨릴 것입니다. 우리는 단어가 아니라 줄을 세고 있습니다! 이 find
중단 될 수 있습니다, 그러나 다시, 우리는 말을 라인을 계산 아닙니다.
touch $'foo\nbar'
빈 디렉토리 안에 명령 중 하나 (예 :)가 있으면 하나가 ls -1 | wc -l
아닌 두 개의 파일이보고됩니다. 하나의 파일은 관련이있는 한 두 줄이기 때문입니다 wc
. ls
개행을 다른 문자로 바꾸지 않는 한 (그렇지 않다고 생각하지만 다시 테스트 할 위치에 있지 않습니다).
wc -c
기간을 계산할 때 문제가 있습니까?
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
파일이 존재하지 않거나 액세스 권한이없는 디렉토리에 있거나 파일 경로를 확인하는 데 루프가있어 유형을 확인할 수없는 파일에 대한 심볼릭 링크 입니다. 내 경우에는 현재 사라진 파일에 대한 심볼릭 링크가있는 2).
그 카운트 없음 .
과 ..
. 만약 당신이 그것들을 포함시키기를 원한다면 (왜 당신은?) 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
첫 번째 GNU 를 다음과 같이 다시 작성할 수 있습니다.
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
사람들은 같은 파일 (대신 디렉토리 항목과 GNU와 파일 수에 아이 노드 672252.와 하나 (하드 링크 일명 파일 이름 일명) 3 개 디렉토리 항목입니다 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
/ usr / bin 아래의 모든 파일을 재귀 적으로 또는 첫 번째 수준 아래로 원한다면 말하지 않았습니다. 또한, 당신이 세는 단어를 어떻게 얻습니까? 알아내는 일반적인 방법은 find를 wc로 실행하는 것입니다. 이와 같이 : find / usr / bin | wc -l Find는 거기에있는 모든 것, 디렉토리 및 파일을 나열합니다. Wc -l은 찾기 출력의 모든 행을 계산합니다. 이것은 수업 과제입니까? 괜찮다면 응답을보다 신중하게 조정할 수 있도록 왜이 정보가 필요한지 궁금합니다. 더 필요한 경우 알려주십시오. 코스타
외부 도구없이 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
.
하지 않으며 카운트 나 ..
항목 도 계산 하지 않습니다 . 파일 대 일반 파일을 명확하게하고 싶을 수도 있습니다.