!["헤드"가 출력하는 것보다 더 많은 입력 라인을 읽거나 소비할 수 있습니까?](https://linux55.com/image/222004/%22%ED%97%A4%EB%93%9C%22%EA%B0%80%20%EC%B6%9C%EB%A0%A5%ED%95%98%EB%8A%94%20%EA%B2%83%EB%B3%B4%EB%8B%A4%20%EB%8D%94%20%EB%A7%8E%EC%9D%80%20%EC%9E%85%EB%A0%A5%20%EB%9D%BC%EC%9D%B8%EC%9D%84%20%EC%9D%BD%EA%B1%B0%EB%82%98%20%EC%86%8C%EB%B9%84%ED%95%A0%20%EC%88%98%20%EC%9E%88%EC%8A%B5%EB%8B%88%EA%B9%8C%3F.png)
다음 3개의 스크립트가 주어졌습니다.
printf 'a\nb\nc\n' > file && { head -n 1; cat; } < file
printf 'a\nb\nc\n' | { head -n 1; cat; }
{ head -n 1; cat; } < <(printf 'a\nb\nc\n')
각각에 대해 내가 기대하는 결과는 다음과 같습니다.
a
b
c
그러나 이러한 시스템 중 일부, 일부 시스템에서는 그렇지 않습니다. 예를 들어, cygwin에서:
$ printf 'a\nb\nc\n' > file && { head -n 1; cat; } < file
a
b
c
$ printf 'a\nb\nc\n' | { head -n 1; cat; }
a
$ { head -n 1; cat; } < <(printf 'a\nb\nc\n')
a
이 스크립트의 출력이 달라지는 원인은 무엇입니까?
추가 정보 - 이것은 단순한 head
문제가 아닌 것 같습니다.
$ printf 'a\nb\nc\n' | { sed '1q'; cat; }
a
$ printf 'a\nb\nc\n' | { awk '1;{exit}'; cat; }
a
$ { sed '1q'; cat; } < <(printf 'a\nb\nc\n')
a
$ { awk '1;{exit}'; cat; } < <(printf 'a\nb\nc\n')
a
입력이 파이프에서 오는지 파일에서 오는지 여부에 관계없이 입력에서 일부 줄을 읽고 나머지는 다른 명령에 맡기는 쉘의 강력한 POSIX 방식(즉, 모든 작업을 수행하기 위해 awk 또는 이와 유사한 것을 한 번만 호출하는 것이 아님)?
이 질문은 답변 아래의 댓글에서 영감을 얻었습니다.특정 열의 값을 기준으로 전체 .csv를 정렬합니다..
답변1
head
가능한전체 입력을 읽으십시오. 그것~ 해야 하다최소한 출력되는 내용을 읽으십시오(그렇지 않으면 논리적으로 불가능함). 그러나 더 많이 읽을 수도 있습니다.
일반적으로 head
운영 체제는 고정된 크기의 데이터를 읽어야 합니다.완충기read
( 시스템 호출 등을 호출하여 ) 그런 다음 해당 버퍼에서 개행 문자를 찾고 원하는 줄 수에 도달할 때까지 출력을 인쇄합니다.
모두POSIX 호환head
호출된 구현은 lseek
입력의 파일 위치를 출력에 복사된 섹션의 끝 바로 뒤로 재설정합니다. 그러나 이는 파일을 검색할 수 있는 경우에만 가능합니다. 여기에는 일반 파일이 포함되지만 파이프는 포함되지 않습니다. 입력이 파이프인 경우 head
읽은 모든 내용은 파이프에서 삭제되며 다시 되돌릴 수 없습니다. 이는 <file
(일반 파일)과 |
또는 (파이프라인) <()
사이에서 관찰한 차이점을 설명합니다.
위 표준의 관련 부분은 다음과 같습니다.
표준 유틸리티가 검색 가능한 입력 파일을 읽고 파일 끝에 도달하기 전에 오류 없이 종료되는 경우 유틸리티는 열린 파일 설명의 파일 오프셋이 유틸리티가 처리한 마지막 바이트 뒤에 올바르게 위치하는지 확인해야 합니다. 검색할 수 없는 파일의 경우 파일의 열린 파일 설명에 있는 파일 오프셋 상태가 지정되지 않습니다. 호환 응용 프로그램은 다음 세 가지 명령이 동일하다고 가정해서는 안 됩니다.
tail -n +2 file (sed -n 1q; cat) < file cat file | (sed -n 1q; cat)
두 번째 명령은 파일을 검색할 수 있는 경우에만 첫 번째 명령과 동일합니다. 세 번째 명령은 열린 파일 설명의 파일 오프셋을 지정하지 않은 상태로 둡니다. head, read 및 sh와 같은 다른 유틸리티도 비슷한 속성을 갖습니다.
ksh93의 내장 구현(이후에 활성화되고 빌드 시 포함됨) head
과 같은 일부 구현 에서는 ksh93의 경우 입력을 검색할 수 없을 때 출력의 마지막 줄에 커서를 유지하지 않으려고 합니다. 입력을 바이트당 한 번 읽거나(셸 내장이 일반적으로 수행함) 또는 다음을 통해 읽습니다.head
builtin head
read
나타나다이것이 가능한 시스템(Linux가 아님)에서 파이프의 내용을 읽기 전에. 그러나 성능에 심각한 영향을 미치므로 이는 예외입니다.