꼬리 반대쪽 : 마지막 n 줄을 제외한 모든 줄


35

유닉스 커맨드 라인 필터로 파일의 마지막 n 줄을 어떻게 버릴 수 있습니까?

그것은 일종의 반대입니다 tail: tail첫 번째 n 줄을 버리고 나머지는 파이프하지만 마지막 n 줄 을 제외한 모든 것을 파이프하는 명령을 원합니다 .

불행히도 나는 그런 것을 찾지 못했습니다 head.도 도움 이되지 않습니다 . 편집 : 적어도 Solaris에서는 부정적인 인수를 취하지 않습니다.

업데이트 : 나는 큰 파일, 즉 로그 파일과 같은 마지막 파일에서 발생한 일을 검사하려는 솔루션에 주로 관심이 있습니다.


head를 사용할 때 참고 : -n 옵션을 사용하여 숫자 앞에 '-'를 배치하면 아래 그림과 같이 각 파일의 모든 줄을 인쇄하지만 마지막 N 줄은 인쇄하지 않습니다.
G Koe

답변:


37

GNU가 있다면 head사용할 수 있습니다

head -n -5 file.txt

의 마지막 5 행을 제외한 모든 행을 인쇄합니다 file.txt.

경우 head -n부정적인 인수를 취하지 않는 시도

head -n $(( $(wc -l file.txt | awk '{print $1}') - 5 )) file.txt

11
(그리고 file.txt최소한 6 줄
이상이

1
슬프게도이 비 GNU 버전은 스트림에서도 작동하지 않습니다.
Armand

1
@ MichaelKjörling 적어도 우분투에서는 문제가되지 않습니다. 파일에 지정된 것보다 적은 행이 head있으면 빈 출력이 반환되고 오류는 없습니다.
Alphaaa

내가 실수하지 않으면 머리 -n 5는 처음 5 줄을 인쇄하고 마지막 5 줄을 제외한 모든 줄을 인쇄합니다.
pypmannetjies

8
head file.txt               # first 10 lines
tail file.txt               # last 10 lines
head -n 20 file.txt         # first 20 lines
tail -n 20 file.txt         # last 20 lines
head -20 file.txt           # first 20 lines
tail -20 file.txt           # last 20 lines
head -n -5 file.txt         # all lines except the 5 last
tail -n +5 file.txt         # all lines except the 4 first, starts at line 5

1
수락 된 답변에 답변되지 않은 추가 사항은 무엇입니까? 또한 다른 답변과 마찬가지로 답변에 대한 몇 가지 설명 줄이 크게 향상됩니다.
music2myear

1
아주 좋은 요약
ruanhao

5

다음은 BSD 등에서 작동하는 마지막 줄을 삭제하는 간단한 방법입니다.

sed '$d' input.txt

표현식은 "마지막 줄에서 삭제합니다"라고 읽습니다. 다른 행은 sed기본 동작 이므로 인쇄됩니다 .

여러 줄을 제거하기 위해 함께 묶을 수 있습니다.

sed '$d' input.txt | sed '$d' | sed '$d'

어느 쪽이 든든하지만, 파일을 통해 한 번만 스캔합니다.

자세한 답변은 https://stackoverflow.com/questions/13380607/how-to-use-sed-to-remove-last-n-lines-of-a-file을 참조하십시오.

여기 내가 좋아하는 것 중 하나에서 적응 한 라이너가 있습니다.

N=10
sed -n -e ':a' -e "1,$N!{P;N;D;};N;ba"

나는 그 것을 해독하는 것이 재미 있었고, 당신도 그렇게하기를 바랍니다 N.


3

왜 당신 head이 옵션이 아니라고 생각하는지 궁금합니다 .

~$ man head
...
-n, --lines=[-]K
        print the first K lines instead of the first 10; 
        with the leading `-', print all but the last K lines of each file

예를 들어 다음을 사용하여 목적에 맞는 것 같습니다.

head -n -20 yourfile.txt

5
이것은 GNU에만 적용됩니다 head. BSD head에는이 옵션이 없으므로 GNU coreutils가없는 Solaris 또는 다른 유닉스 에서는 이 답변이 작동 하지 않습니다 . OP는 특히 Unix 및 Unix-Utils로 태그를 지정했습니다.
slhck

2
@slhck OP가 이것이 Solaris를위한 것이라고 언급했다는 사실은 말할 것도 없습니다.
CVn

불행히도 누군가 Solaris에 대한 언급을 제거했습니다. 그러나 어쨌든 head 버전은 그것을 지원하지 않는다고 언급 했어야합니다.
Hans-Peter Störr

1
모두 죄송합니다. Solaris를 눈치 채지 못했고 다양한 버전의 헤드를 알지 못했습니다.
Anders R. Bystrup

1
@hstoerr Solaris 태그에 지금 :)
slhck

0

tail -n부정적인 주장을 취하지 않을 경우 다른 방법 은

tac file.txt | tail -n +6 | tac

이것은 마지막 5 줄을 제거합니다


감사! 그것은 지금까지 아무도 생각해 낸 멋진 아이디어입니다. 불행히도 이것은이 질문에 염두에 둔 유스 케이스에는 상당히 비효율적입니다. 큰 파일 인 경우 다른 솔루션과 마찬가지로 한 번 이상 완전히 읽을뿐만 아니라 아마도 다음과 같이 쓰여질 것입니다. 메모리에 맞지 않으면 tac로 임시 파일을 디스크에 넣습니다.
Hans-Peter Störr

@ Hans-Peter 매우 사실입니다. python3 스크립트를 작성하기로 결정했습니다. 이 github.com/atw31337/donkey를 사용해보십시오 . 출력 옵션을 사용하는 것이 좋습니다. 리디렉션을 사용하는 것보다 훨씬 빠르게 실행됩니다.
atw31337

멋지게 작성되었습니다! 그러나 파일을 두 번 읽습니다. 마지막 n 줄을 버퍼링하는 경우 실제로 필요하지 않으므로 큰 파일에서 문제가됩니다. 개인적으로, 나는 더 이상 그것을 필요로하지 않지만, 당신이 그것을 개선하고 다른 사람들이 그것을 필요로하는 경우를 대비하여 ... 결국에는 몇 가지 좋아하고 북마크가있었습니다.
Hans-Peter Störr

@ Hans-Peter. 버퍼 크기는 제거 할 행 수에 따라 다릅니다. 파일에서 매우 많은 수의 행을 삭제해야하는 경우 문제가 될 수 있습니다. 메모리 관련 문제를 피하기 위해, n 값이 높은 라인 카운트 방법과 n 값이 낮은 버퍼링 방법을 사용하도록 스크립트를 다시 작성했습니다. 그러나 매우 큰 파일로 테스트 한 후에도 원래 줄 수 방법이 더 빠릅니다. 버퍼 관리 오버 헤드가 라인 수 오버 헤드보다 큰 것 같습니다. 또는 뭔가 빠진 것 같습니다.
atw31337

좋지만 BSD 변형 Mac OS X의 경우 기본적으로 tac 명령이 없습니다. :( 패배의이 종류를 사용하는 경우.
ingyhere
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.