wc와 파이프를 사용하여 특정 디렉토리에 얼마나 많은 파일과 디렉토리가 있는지 확인하는 방법은 무엇입니까?

wc와 파이프를 사용하여 특정 디렉토리에 얼마나 많은 파일과 디렉토리가 있는지 확인하는 방법은 무엇입니까?

디렉토리에 얼마나 많은 파일이나 디렉토리가 있는지 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

여기에서는 현재 디렉토리의 모든 항목( 제외 ..)을 찾고 각각에 대해 점( )을 인쇄한 다음 줄 대신 바이트 수를 계산하는 기능을 .사용하여 점 수를 계산합니다 .wcwc -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

관련 정보