`wc -l`은 어떻게 작동합니까?


11

큰 파일을 읽어야하며, 읽기 시작하기 전에 파일의 총 줄 수 (백만 단위)를 알아야합니다.

많은 솔루션을 구현했으며 하나를 찾았습니다. 그러나 검색하는 동안 어떻게 wc -l작동 하는지 살펴보고 싶었습니다 . Google에서 찾을 수 없습니다.

내 문제에 대한 해결책을 찾았지만 wc -l몇 초 안에 92 백만 줄의 파일 줄 수를 계산할 수 있으므로 어떻게 작동 하는지 알고 싶습니다 !

어떻게?


답변:


20

전체 파일을 읽고 줄 끝 수를 계산합니다. 줄 끝을 계산하는 것은 정말 저렴합니다. 대부분의 시간은 파일을 읽는 것입니다. 파일이 버퍼 캐시에 (대부분) 있다면, 그것도 싸다. 그렇지 않으면 파일 저장 속도에 따라 다릅니다.

다시 말해, 마법이 없습니다.


전체 파일을 읽고 줄 끝 수를 계산합니까? 줄 끝까지 가려면 기본적으로 끝까지 도달 할 때까지 전체 줄을 읽지 않습니까? 그리고 그것은 전체 파일을 읽었 음을 의미합니다.
detraveller

@detraveller : 예, 내가 말한 것처럼 전체 파일을 읽습니다. 한 줄씩 읽거나 한 번에 읽지 않지만 모든 문자를 읽고 해당 문자 중 줄 끝 문자 수를 계산합니다.
rici

7

WC는 파일을 원시 바이트 블록으로 읽습니다 (파일이있는 기본 파일 시스템의 자연 블록 크기의 배수로 권장).
그런 다음 줄 끝 문자를 계산하는 버퍼를 검색합니다. -l 출력 이외의 정보를 원할 경우를 대비하여 공백, 탭, 용지 공급 및 기타 특수 문자도 계산합니다.

디스크 읽기는 속도 측면에서 비용이 많이 듭니다. 버퍼의 스캔은 그에 비해 무시할 수있는 시간이 걸립니다.

한 줄에 평균 100자인 9 천만 줄이 있다고 가정 해 봅시다.
약 9.000.000.000 자 또는 약 860MB입니다.
SATA-3Gb / s 드라이브가 장착 된 알맞은 PC는 10 초 이내에이를 수행합니다. 다른 활동이 동시에 진행되는 비교적 느린 파일 시스템에서도.
SATA-6G 및 SSD 드라이브에 의존하지 않아도 일부 성능 조정 및 최적화 된 파일 시스템을 갖춘 빠른 ​​시스템은 5 초 이내에이를 수행 할 수 있습니다.


그것은 줄 끝 \n문자 ( )를 세는 버퍼를 스캔합니다. "-l,-줄은 줄 바꿈 카운트를 출력합니다 \ n \"-에서 추출wc.c
Rahul Patil

@RahulPatil 대부분의 구현은 개행을 계산하는 것 이상을 수행합니다. 위의 상단 주석에 언급 된 예를 참조하십시오. 이것이 Linux 핵심 유틸리티에서 사용되는 wc의 소스입니다.
Tonny

네 .. 나는 그것을 보았다 .. 그냥 언급 때문에 wc -l.. 죄송합니다 ...
Rahul Patil

3

자유 소프트웨어의 세계에 오신 것을 환영합니다. 당신은 항상 소스 코드를 볼 수 있습니다

난 당신 (내가 정말 코드를 설명 할 수있는 사람이 아니에요 그래서, C 프로그래머가 아니에요 것을 인정해야하지만 자신을 insterested 수).

내가 아는 것은 wc가 파일 자체를 열지 않지만 OS에게 파일을 요청하기 때문에 OS에 달려 있으며 물론 파일 저장 방법에 달려 있습니다. 그 외에도 파일을 한 번에 전체적으로 읽지 않는 등 올바른 프로그래밍 방법을 갖추어야합니다.


'전체 파일을 한 번에 읽으려고하지 않는다'는 말은 무슨 뜻입니까?
detraveller

파일을 메모리, 예를 들어 단일 문자열 / 배열로로드하는 것을 의미합니다. Perl 커뮤니티에서는 이것을 슬러 핑 (surping)이라고하며, 몇 줄을 읽게 될 것임을 알면 신속하고 더러운 솔루션입니다 . 그러나 한 번에 정말 큰 파일을 메모리에 공급하는 것은 좋은 생각이 아닙니다.
Alois Mahdal

1
반면에 64 KiB를 읽고, 줄 바꿈을 세어 버리고, 반복 할 수 있습니다 ... 그렇게하면 파일의 크기에 관계없이 최대 64 KiB 이상을 먹을 수 있습니다. (개행은 2 바이트를 가질 수 있고 따라서 2 개의 청크로 나눌 수 있다는 것을
알면 쉽지 않다

너무 중요하지는 않지만 "wc는 파일 자체를 열지 않지만 OS에게 파일을 요청하기 때문에" -그 의미가 무엇인지 확실하지 않지만 이것이 올바른지 의심합니다. 확실히 모든 문자를 자체적으로 읽습니다.
Arjan

2
@Arjan 비록 정확하다. 임베디드 시스템을 제외하고 프로그램은 실제로 자체적으로 읽기를 거의하지 않는다. 커널과 OS의 요점은 그것들을 위해 일한다는 것이다. 실제로 open (), close (), read () (Linux, Windows, 소켓 또는 파일)는 실제 프로그램이 내부 작업에 대해 전혀 알지 못하는 모든 시스템 호출입니다.
Alois Mahdal
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.