WC와 파이핑을 사용하여 특정 디렉토리에 몇 개의 파일과 디렉토리가 있는지 찾는 방법은 무엇입니까?


10

단어 카운터 ( wc) 및 파이핑을 사용하여 /usr/bin디렉토리 에있는 파일 또는 디렉토리 수를 계산할 수 있습니까?


이 숙제 ?? 도움을 요청하는 것이 좋습니다 (있는 경우).
slm

그렇습니다.하지만 Linux를 처음 사용하기 때문에 무언가를 달성하는 방법에 대한 아이디어를 얻으려면 여기에 게시하십시오. 매우 복잡 할 수 있습니다. 그리고 나는 이미이 명령으로 위의 문제를 해결했습니다
현금

ls / bin / usr / bin | 정렬 | 유니크 | 화장실 -
현금

np. 도움을 요청하는 것이 좋습니다. 사람들에게 알릴 수 있도록 레이블을 붙이십시오. 여기있는 모든 사람들은 일반적으로 유닉스의 훌륭한 점을 배우려는 사람들을 기꺼이 도와줍니다.
slm

답변:


13

한 가지 방법은 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 구현을 사용하는 경우이 문제를 해결하는 한 가지 방법 findfind찾은 각 파일 대신 다른 것을 인쇄 한 다음 대신 그 수를 세는 기능을 사용하는 것입니다.

$ find . -printf . | wc -c
9

여기서는 현재 디렉토리에서 모든 것을 찾고 (을 제외하고 ..) .각각에 대해 점 ( )을 인쇄 한 다음 wc줄 대신 바이트를 계산하는 능력을 사용하여 점을 계산합니다 wc -c.

참고 문헌


파일의 형식 /usr/bin이 모두 잘 지정되고 (공백이 포함되어 있지 않으므로 기술적으로도 가능할 수 있지만 echo * | wc -w) 개행 문자가 포함 된 파일 이름에서 이러한 파일이 모두 손상 될 수 있습니다.
evilsoup

@evilsoup-아니오 나는 믿지 ls -l않거나 ls -1b / c를 깨뜨릴 것입니다. 우리는 단어가 아니라 줄을 세고 있습니다! 이 find중단 될 수 있습니다, 그러나 다시, 우리는 말을 라인을 계산 아닙니다.
slm

내가 의미하는 바는 파일에 줄 바꿈이 포함되어 있으면 이것이 (현재 Windows에 있으므로 테스트 할 수 없다고 생각 함) 것 입니다. 따라서 touch $'foo\nbar'빈 디렉토리 안에 명령 중 하나 (예 :)가 있으면 하나가 ls -1 | wc -l아닌 두 개의 파일이보고됩니다. 하나의 파일은 관련이있는 한 두 줄이기 때문입니다 wc. ls개행을 다른 문자로 바꾸지 않는 한 (그렇지 않다고 생각하지만 다시 테스트 할 위치에 있지 않습니다).
evilsoup

@evilsoup-올바른 줄 바꿈 문자. 합법적 인 문자입니다. 파일 이름의 경우, 메소드는 이러한 유형의 파일 이름과 올바르게 경쟁 할 수 없습니다.
slm

@StephaneChazelas- wc -c기간을 계산할 때 문제가 있습니까?
slm

5

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

0

/ usr / bin 아래의 모든 파일을 재귀 적으로 또는 첫 번째 수준 아래로 원한다면 말하지 않았습니다. 또한, 당신이 세는 단어를 어떻게 얻습니까? 알아내는 일반적인 방법은 find를 wc로 실행하는 것입니다. 이와 같이 : find / usr / bin | wc -l Find는 거기에있는 모든 것, 디렉토리 및 파일을 나열합니다. Wc -l은 찾기 출력의 모든 행을 계산합니다. 이것은 수업 과제입니까? 괜찮다면 응답을보다 신중하게 조정할 수 있도록 왜이 정보가 필요한지 궁금합니다. 더 필요한 경우 알려주십시오. 코스타


0

외부 도구없이 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

두 번째는 되풀이 할 때 심볼릭 링크를 따르고 (일반 파일에 대한 심볼릭 링크를 일반 파일로 계산하고, 디렉토리에 대한 디렉토리를 dirs로 계산) 현재 디렉토리의 파일과 디렉토리를 카운트 .하지 않으며 카운트 나 ..항목 도 계산 하지 않습니다 . 파일 대 일반 파일을 명확하게하고 싶을 수도 있습니다.
Stéphane Chazelas
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.