Bash의 파일에서 마지막 줄을 제거하십시오.


답변:


406

사용 GNU sed:

sed -i '$ d' foo.txt

-i옵션은 GNU sed3.95 이전 버전 에는 존재하지 않으므로 임시 파일이있는 필터로 사용해야합니다.

cp foo.txt foo.txt.tmp
sed '$ d' foo.txt.tmp > foo.txt
rm -f foo.txt.tmp

물론이 경우 head -n -1대신 대신 사용할 수도 있습니다 sed.

맥 OS:

Mac OS X (10.7.4 기준)에서 sed -i위 의 명령에 해당하는 것은

sed -i '' -e '$ d' foo.txt

56
Mac OS X (10.7.4 기준)에서 sed -i위 의 명령 과 같습니다 sed -i '' -e '$ d' foo.txt. 또한 head -n -1현재 Mac에서는 작동하지 않습니다.
mklement0

26
'$ d'정규식이 무엇을 설명 할 수 있습니까? 마지막 줄을 제거하는 것에 대한 질문 이므로이 질문을 보는 모든 사람에게 이것이 가장 중요한 부분이라고 생각합니다. 감사합니다 :)
kravemir

38
@Miro : 결코 $ d정규 표현식 이 아닙니다 . sed 명령입니다. d행을 삭제하는 명령이며 $"파일의 마지막 행" 을 의미합니다. 명령 전에 위치 (sed lingo에서 "range"라고 함)를 지정하면 해당 명령은 지정된 위치에만 적용됩니다. 따라서이 명령은 "파일의 마지막 행 범위에서 삭제합니다"라고 명시 적으로 표시합니다. 당신이 나에게 묻는다면, 꽤 매끄럽고 바로 포인트.
Daniel Kamil Kozar

1
빈 줄인 경우에만 마지막 줄을 어떻게 제거합니까?
skan

1
@Alex : GNU sed 용으로 업데이트되었습니다. 다양한 BSD / UNIX / MacOS sed 버전에 대해 전혀 모른다 ...
thkala

279

이것은 특히 가장 큰 파일에서 가장 빠르고 간단한 솔루션입니다.

head -n -1 foo.txt > temp.txt ; mv temp.txt foo.txt

최상위 줄을 삭제하려면 다음을 사용하십시오.

tail -n +2 foo.txt

이것은 라인 2에서 시작하는 출력 라인을 의미합니다.

sed파일의 맨 위나 맨 아래에서 줄을 삭제 하는 데 사용하지 마십시오 . 파일이 크면 속도가 매우 느립니다.


16
head -n -1 foo.txt충분하다
ДМИТРИЙ МАЛИКОВ

20
head -n -1은 bdsutils의 head에서 작동하지 않습니다. 적어도 macos가 사용중인 버전에는 없으므로 작동하지 않습니다.
johannes_lalala

23
@johannes_lalala Mac에서는 brew install coreutils(GNU 핵심 유틸리티) ghead대신을 사용할 수 있습니다 head.
흥미롭게도

다음은 간단한 bash는 스크립트는 하단에 라인의 다른 수의 여러 파일이 경우 자동화 그것을 삭제하는 것입니다 : 고양이 TAILfixer FILE=$1; TAIL=$2; head -n -${TAIL} ${FILE} > temp ; mv temp ${FILE}실행 그것으로 myfile을에서 예를 들어 4 개 라인을 삭제하는 : ./TAILfixer myfile 4의 물론 첫번째로 그것을 실행하기chmod +x TAILfixer
FatihSarigol

그것이 효과가 있었기 때문에 엄지 손가락이지만,에 대한 모든 비교를 위해 sed,이 명령은 꽤 느리다
Jeff Diederiks

121

HUGE 파일 (~ 300Gb)로 작업하고 솔루션이 확장되지 않았기 때문에 모든 대답에 문제가있었습니다. 내 해결책은 다음과 같습니다.

dd if=/dev/null of=<filename> bs=1 seek=$(echo $(stat --format=%s <filename> ) - $( tail -n1 <filename> | wc -c) | bc )

말로 : 끝내려는 파일의 길이 (을 사용하여 파일 길이에서 마지막 줄 길이의 길이를 뺀 값)를 찾은 bc다음 해당 위치를 파일의 끝으로 설정하십시오 ( dd1 바이트 /dev/null를 그것).

이것은 tail끝에서부터 읽기 시작 하기 때문에 빠르며 dd, 파일의 모든 줄을 복사 (및 구문 분석)하는 대신 파일 덮어 쓰므로 다른 솔루션이 수행합니다.

참고 : 이렇게하면 파일에서 줄이 제거됩니다. 자신의 파일로 시도하기 전에 더미 파일을 백업하거나 테스트하십시오!


3
나는 dd에 대해 몰랐다. 이것이 최고의 답변이어야합니다. 정말 고맙습니다! gzip으로 압축 된 파일에 대해 솔루션이 작동하지 않는 것은 부끄러운 일입니다.
tommy.carstensen

4
매우 영리한 접근법! 참고 사항 : 실제 파일이 필요하고 작동하므로 파이프, 명령 대체, 리디렉션 및 이러한 체인에서는 사용할 수 없습니다.
MestreLion

3
이것이 최고의 답변이어야합니다. ~ 8GB 파일을 즉시 처리했습니다.
피터 코간

8
mac 사용자 : dd if = / dev / null of = <filename> bs = 1 seek = $ (echo $ (stat -f = % z <filename> | cut -c 2-)-$ (tail -n1 <filename> | wc -c) | bc)
Igor

2
이 방법은 대용량 파일을위한 방법입니다!
thomas.han

61

파일에서 마지막 줄을 제거하려면 전체 파일을 읽거나 아무것도 재 작성하지 않고 , 당신은 사용할 수 있습니다

tail -n 1 "$file" | wc -c | xargs -I {} truncate "$file" -s -{}

마지막 행을 제거하고 stdout ( "pop")에 인쇄하려면 해당 명령을 tee다음 과 결합하면됩니다 .

tail -n 1 "$file" | tee >(wc -c | xargs -I {} truncate "$file" -s -{})

이러한 명령은 매우 큰 파일을 효율적으로 처리 할 수 ​​있습니다. 이것은 Yossi의 답변과 비슷하고 영감을 얻었지만 몇 가지 추가 기능을 사용하지 않습니다.

이것을 반복적으로 사용하고 오류 처리 및 다른 기능을 원한다면 poptail여기 에서 명령을 사용할 수 있습니다 : https://github.com/donm/evenmoreutils


3
빠른 참고 : truncateOS X에서는 기본적으로 사용할 수 없습니다. 그러나 Brew :를 사용하여 쉽게 설치할 수 brew install truncate있습니다.
기 illa 부데요 우

3
아주 좋아요 dd가 없으면 훨씬 좋습니다. 나는 재앙을 불러올 수있는 하나의 잘못된 숫자 나 문자로 DD를 사용 무서웠다 .. +1
요시 Farjoun을

1
(JOKE 경고) 실제로, ( "dd"-> "재해")는 1 개의 치환과 6 개의 삽입이 필요합니다. "잘못 놓인 단일 숫자 또는 문자"는 거의 없습니다. :)
Kyle

29

맥 사용자

파일 자체를 변경하지 않고 마지막 줄에서 삭제 된 출력 만 원하면

sed -e '$ d' foo.txt

입력 파일 자체의 마지막 줄을 삭제하려면

sed -i '' -e '$ d' foo.txt


이것은 나를 위해 작동하지만 이해하지 못합니다. 어쨌든 효과가있었습니다.
Melvin

플래그 -i ''는 sed가 파일을 제자리에서 수정하고 확장자를 매개 변수로 제공 한 파일에 백업을 유지하도록 지시합니다. 매개 변수가 빈 문자열이므로 백업 파일이 작성되지 않습니다. -esed에게 명령을 실행하도록 지시합니다. 명령 $ d은 다음을 의미합니다 : 마지막 줄 ( $)을 찾아서 삭제합니다 ( d).
Krzysztof Szafranek

24

Mac 사용자의 경우 :

Mac에서는 head -n -1이 작동하지 않습니다. 그리고 "head"및 / 또는 "tail"명령 만 사용하여이 문제를 해결하기위한 처리 시간에 대한 걱정없이 간단한 해결책을 찾으려고 노력했습니다.

다음과 같은 일련의 명령을 시도했지만 "tail"명령을 사용하여 문제를 해결할 수있어서 기뻤습니다 [Mac에서 사용 가능한 옵션]. 따라서 Mac을 사용 중이고 "꼬리"만 사용하여이 문제를 해결하려는 경우 다음 명령을 사용할 수 있습니다.

고양이 file.txt | 꼬리 -r | 꼬리 -n +2 | 꼬리 -r

설명 :

1> tail -r : 단순히 입력의 라인 순서를 반대로 바꿉니다.

2> tail -n +2 : 입력의 두 번째 줄부터 시작하여 모든 줄을 인쇄합니다.


2
브루을 사용하여로 coreutils를 설치하는 것은 당신이 할 수 있도록 당신에게 'ghead'로 GNU 헤드를 줄 것이다ghead -n -1
somewhatoff

13
echo -e '$d\nw\nq'| ed foo.txt

2
파일을 제자리에서 편집하지 않는 필터 솔루션의 경우을 사용하십시오 sed '$d'.
lhf

8
awk 'NR>1{print buf}{buf = $0}'

기본적으로이 코드는 다음과 같이 말합니다.

첫 번째 줄 이후의 각 줄에 대해 버퍼링 된 줄을 인쇄하십시오.

각 라인에 대해 버퍼를 재설정

버퍼는 한 줄씩 지연되므로 라인 1에서 n-1까지 인쇄하게됩니다.


2
이 솔루션은 필터이며 파일을 제자리에 편집하지 않습니다.
lhf


0

이러한 솔루션은 모두 다른 형식으로되어 있습니다. 나는 이것들이 조금 더 실용적이고 명확하며 유용하다는 것을 알았습니다.

dd 사용 :

BADLINESCOUNT=1
ORIGINALFILE=/tmp/whatever
dd if=${ORIGINALFILE} of=${ORIGINALFILE}.tmp status=none bs=1 count=$(printf "$(stat --format=%s ${ORIGINALFILE}) - $(tail -n${BADLINESCOUNT} ${ORIGINALFILE} | wc -c)\n" | bc )
/bin/mv -f ${ORIGINALFILE}.tmp ${ORIGINALFILE}

자르기 사용 :

BADLINESCOUNT=1
ORIGINALFILE=/tmp/whatever
truncate -s $(printf "$(stat --format=%s ${ORIGINALFILE}) - $(tail -n${BADLINESCOUNT} ${ORIGINALFILE} | wc -c)\n" | bc ) ${ORIGINALFILE}

아야. 너무 복잡합니다.
Robert

0

리눅스

$는 마지막 줄이며 d는 삭제입니다.

sed '$d' ~/path/to/your/file/name

맥 OS

sed -i와 동일

sed -i '' -e '$ d' ~/path/to/your/file/name

0

수동으로 수행 할 수있는 방법은 다음과 같습니다 (파일의 마지막 줄을 빠르게 제거해야 할 때 개인적 으로이 방법을 많이 사용합니다).

vim + [FILE]

+ 기호는 vim 텍스트 편집기에서 파일을 열 때 커서가 파일의 마지막 줄에 위치 함을 의미합니다.

이제 d키보드 를 두 번 누르 십시오. 이렇게하면 원하는대로 정확하게 수행 할 수 있습니다. 마지막 줄을 제거하십시오. 그 후, Enter 키를 눌러 :다음 x을 누른 다음을 누릅니다 Enter. 변경 사항이 저장되고 셸로 돌아갑니다. 이제 마지막 줄이 성공적으로 제거되었습니다.


2
단순성 에 대한 강조 는 여기서 잃어 버렸습니다
Peter M

-4

루비 (1.9+)

ruby -ne 'BEGIN{prv=""};print prv ; prv=$_;' file
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.