왜 'ls -l'이 나보다 많은 파일을 계산합니까?


25

분명히 나는 ​​셀 수 없습니다. 세 개의 파일이 있다고 생각합니다./media

$ tree /media
/media
├── foo
├── onex
└── zanna
3 directories, 0 files

그러나 ls -l12를 찾습니다.

$ ls -l /media
total 12
drwxr-xr-x  2 root root 4096 Jul 31 20:57 foo
drwxrwxr-x  2 root root 4096 Jun 26 06:36 onex
drwxr-x---+ 2 root root 4096 Aug  7 21:17 zanna

내가 할 경우에, ls -la나는 단지 수 ...위뿐만 아니라,하지만 수는있다total 20

설명이 뭐야?

답변:


33

12당신이 볼은 파일의 개수가 아니라 디스크 블록의 수를 소비했다.

보낸 사람 info coreutils 'ls invocation':

 For each directory that is listed, preface the files with a line
 `total BLOCKS', where BLOCKS is the total disk allocation for all
 files in that directory.  The block size currently defaults to 1024
 bytes, but this can be overridden (*note Block size::).  The
 BLOCKS computed counts each hard link separately; this is arguably
 a deficiency.

총에서 이동 1220사용할 때 ls -la대신 ls -l두 개의 추가 디렉토리를 계산하기 때문에 : .... 총 3 × 4 5 × 4. (십중팔구, 당신이 사용하는에서 진행 있도록, 각 (빈) 디렉토리에 네 개의 디스크 블록을 사용하는 하나 개의 각 디렉토리에 대한 4096 바이트의 디스크 블록을하며 같은 info페이지가 표시의 유틸리티는 디스크 형식을 확인하지 않지만 1024별도의 지시가없는 한 블록 크기를 가정합니다 .)

단순히 파일 수를 얻으려면 다음과 같이 시도하십시오.

ls | wc -l

13
ls | wc -l파일 이름에 줄 바꿈이있는 파일이 있으면 실패합니다. find . -mindepth 1 -maxdepth 1 -printf . | wc -c
Flimm

20
"파일 이름에 새 줄이 있으면"... 떨림
Petah

8
알다시피 man ls, 제어 문자를 사용하여 -b(이스케이프) 또는 -q(생략 ) 피할 수 있습니다 . 따라서 계산을 ls -1q | wc -l위해 숨겨지지 않은 파일을 표시하는 데 안전하고 정확합니다. ls -1qA | wc -l숨겨진 파일을 계산합니다 ( ...제외). 나는 그것이 더 빠르기 때문에 -1대신에 사용 -l하고 있습니다.
Oli

18

user4556274 님은 이미이유에 답변하셨습니다 . 내 대답은 파일을 올바르게 계산 하는 방법 에 대한 추가 정보를 제공하는 것 입니다.

유닉스 커뮤니티에서 일반적인 합의는 파일 이름에 제어 문자 또는 숨겨진 문자가 포함될 수 있기 때문에 출력ls구문 분석 하는 것은 매우 나쁜 생각 입니다. 예를 들어 파일 이름의 줄 바꿈 문자로 인해 ls | wc -l출력에 5 줄이 ls있지만 실제로는 디렉토리에 파일이 4 개뿐입니다.

$> touch  FILE$'\n'NAME                                                       
$> ls                                                                         
file1.txt  file2.txt  file3.txt  FILE?NAME
$> ls | wc -l
5

방법 # 1 : 유틸리티 찾기

find일반적으로 주위에 작업 파일 이름을 구문 분석에 사용되는 명령은, 인쇄에 의해 여기 우리를 도울 수 inode 번호를 . 디렉토리 또는 파일이면 하나의 고유 한 inode 번호 만 있습니다. 따라서 via를 사용 -printf "%i\n"하고 제외 하면 정확한 파일 수를 가질 수 있습니다. ( 하위 디렉토리로 재귀 내림차순을 방지하기위한 사용에 유의하십시오 ).-not -name "."-maxdepth 1

$> find  -maxdepth 1 -not -name "." -print                                    
./file2.txt
./file1.txt
./FILE?NAME
./file3.txt
$> find  -maxdepth 1 -not -name "." -printf "%i\n" | wc -l                    
4

방법 # 2 : globstar

간단하고 빠르며 주로 이식 가능한 방법 :

$ set -- * 
$ echo $#
228

set명령은 쉘의 위치 매개 변수 (에서 $<INTEGER>와 같은 변수) 를 설정하는 데 사용됩니다 echo $1. 이것은 종종 /bin/sh배열 부족의 한계 를 해결하는 데 사용됩니다 . 추가 검사를 수행하는 버전은 Unix & Linux에 대한 Gille의 답변 에서 찾을 수 있습니다 .

등의 지원 배열, 즉 쉘에서 bash, 우리가 사용할 수 있습니다

items=( dir/* )
echo ${#items[@]}

의견에서 steeldriver가 제안한대로 .

find사용 된 방법 wc과 비슷한 속임수 와 globstar를 사용하여 한 stat줄 당 inode 수를 계산할 수 있습니다 .

$> LC_ALL=C stat ./* --printf "%i\n" | wc -l                                          
4

다른 방법은 와일드 카드 인 for루프 를 사용하는 것 입니다. (이 테스트는 다른 디렉토리를 사용하여이 방법이 하위 디렉토리로 내려가는 지 여부를 테스트합니다.-16은 내에서 확인 된 항목 수입니다. ~/bin)

$> count=0; for item in ~/bin/* ; do count=$(($count+1)) ; echo $count ; done | tail -n 1                                
16

방법 # 3 : 다른 언어 / 통역사

파이썬은 또한 내 os.listdir()함수가 주어진 목록의 길이를 인쇄하여 문제가있는 파일 이름을 처리 할 수 ​​있습니다 (비 재귀 적이며 인수로 제공된 디렉토리의 항목 만 나열합니다).

$> python -c "import os ; print os.listdir('.')"                              
['file2.txt', 'file1.txt', 'FILE\nNAME', 'file3.txt']
$>  python -c "import os ; print(len(os.listdir('.')))"                    
4

참조


2
bash에서 또 다른 옵션은 배열을 사용하는 것입니다 items=( dir/* ); echo ${#items[@]}( 예 : shopt -s dotglob숨겨진 파일 포함).
스틸 드라이버

1
inode 번호를 인쇄하면 원하는 경우 하드 링크를 쉽게 필터링 할 수 find | sort -u | wc -l있습니다.
Peter Cordes

@steeldriver : bash-array 방법이 더 빠를 것 같지 않습니다. 재귀 적으로 사용하려면 items=( dir/** )(with shopt -s globstar) 를 사용해야 하지만 bash는 readdir의 추가 메타 데이터를 활용하지 않으므로 모든 디렉토리 항목을 통계하여 디렉토리 자체인지 확인합니다. 많은 파일 시스템은 파일 유형을 디렉토리 항목에 저장하므로 readdir은 inode에 액세스하지 않고 파일 유형을 반환 할 수 있습니다. (예를 들어, 최신의 기본이 아닌 XFS는 이것을 가지고 있으며, ext4가 더 오랫동안 가지고 있다고 생각합니다.) 찾으면 bash 추적 strace보다 stat시스템 호출이 훨씬 적습니다 .
Peter Cordes

2
왜 사용하지 print(len(os.listdir('.')))않습니까? 입력 할 문자 수가 적고 이중 밑줄 속성에 액세스하지 않습니다.
edwinksl

1
@edwinksl 편집 됨, thx
Sergiy Kolodyazhnyy
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.