tail
25GB 텍스트 tail
파일을 원하면 명령이 전체 파일을 읽습니까?
파일이 디스크에 흩어져있을 수 있기 때문에 파일이 필요하다고 생각하지만 그러한 내부 구조를 잘 이해하지 못합니다.
답변
아니요, tail
전체 파일을 읽지 않고 끝까지 검색 한 다음 예상 줄 수에 도달 할 때까지 블록을 뒤로 읽은 다음 파일 끝까지 올바른 방향으로 행을 표시하고 -f
옵션이 사용되는 경우 파일 .
그러나 tail
파이프에서 읽을 때와 같이 검색 할 수없는 입력이 제공된 경우 전체 데이터를 읽는 것 외에는 선택의 여지가 없습니다.
마찬가지로, 지원되는 경우 tail -n +linenumber
구문 또는 tail +linenumber
비표준 옵션 을 사용하여 파일 시작 부분부터 시작하여 줄을 찾도록 요청 tail
하면 전체 파일을 읽습니다 (중단되지 않은 경우).
답변
tail
자신이 어떻게 작동 하는지 볼 수 있습니다 . 내 파일 중 하나에 대해 read
세 번 수행되며 총 약 10K 바이트를 읽습니다.
strace 2>&1 tail ./huge-file >/dev/null | grep -e "read" -e "lseek" -e "open" -e "close"
open("./huge-file", O_RDONLY) = 3
lseek(3, 0, SEEK_CUR) = 0
lseek(3, 0, SEEK_END) = 80552644
lseek(3, 80551936, SEEK_SET) = 80551936
read(3, ""..., 708) = 708
lseek(3, 80543744, SEEK_SET) = 80543744
read(3, ""..., 8192) = 8192
read(3, ""..., 708) = 708
close(3) = 0
답변
파일이 디스크에 흩어져있을 수 있기 때문에 [파일을 순차적으로 읽어야한다] 고 생각하지만 그러한 내부 구조를 잘 이해하지 못합니다.
아시다시피, tail
파일의 끝 부분 (시스템 호출 lseek
)을 찾고 뒤로 작동합니다. 그러나 위에서 인용 한 말에서 “꼬리가 파일의 끝을 찾기 위해 디스크의 어디에 있는지 어떻게 알 수 있습니까?”
대답은 간단하다 : 꼬리는 모른다. 사용자 수준 프로세스는 파일을 연속 스트림으로 인식하므로 tail
파일 시작의 오프셋을 알 수 있습니다. 그러나 파일 시스템에서 파일의 “inode”(디렉토리 항목)는 파일 데이터 블록의 물리적 위치를 나타내는 숫자 목록과 연관됩니다. 파일을 읽을 때 커널 / 장치 드라이버는 필요한 부분을 파악하고 디스크상의 위치를 파악하여 가져옵니다.
그것은 우리가 운영 체제를 가지고있는 종류입니다. 따라서 파일 블록이 어디에 흩어져 있는지 걱정할 필요가 없습니다.
답변
head
또는 전체 파일을 읽는 tail
것으로 보이면 파일에 줄 바꿈 문자가 거의 없거나 전혀 없기 때문일 수 있습니다 . 몇 달 전에 문자열이 아닌 공백이 없어도 직렬화 된 매우 큰 (기가 바이트) JSON 블롭 으로이 문제를 해결했습니다.
GNU head / tail이 있다면 line 대신 -c N
첫 번째 / 마지막 N 바이트 를 인쇄하는 데 사용할 수 있지만 불행히도 이것은 POSIX 기능이 아닙니다.
답변
당신은에서 볼 수 있듯이 소스 코드 라인 (525), 당신은 구현에 대한 설명을 볼 수 있습니다.
/* Print the last N_LINES lines from the end of file FD.
Go backward through the file, reading 'BUFSIZ' bytes at a time (except
probably the first), until we hit the start of the file or have
read NUMBER newlines.
START_POS is the starting position of the read pointer for the file
associated with FD (may be nonzero).
END_POS is the file offset of EOF (one larger than offset of last byte).
Return true if successful. */