파일의 마지막 줄을 가져온 다음 삭제하려고 합니다.
다음 줄을 읽어보세요:
sed -n '$p' file
# or
tail -n 1 file
다음 줄을 삭제하세요.
sed -i '$d' file
이게 효과가 있긴 한데, 이렇게 할 수 있는 방법이 있나요?단일 명령?
답변1
대중의 의견이 무엇이든, 파일의 마지막 줄을 잘라내려면 매번 전체 파일을 읽어야 합니다.무음, 단일 프로세스/명령으로 수행되거나 2~3개의 프로세스/명령으로 수행되는지 여부.
sed -i
와 달리 tail
파일의 마지막 줄을 결정하기 위해 처음부터 파일을 읽지 않을 만큼 똑똑합니다. 또한 Linux에는 O(1) 시간 안에 큰 파일의 끝을 "팝"할 수 있는 truncate(1)
유틸리티가 있습니다.tail
# usage popline file [line_count, 1 by default]
popline()(LC_CTYPE=C; l=`tail -n "${2:-1}" "$1"; echo t`; l=${l%t}; truncate -s "-${#l}" "$1"; printf %s "$l")
$ wc -l /tmp/foo
3579500 /tmp/foo
$ cp /tmp/foo /tmp/foo1 && time sed -i '$d' /tmp/foo1
real 0m1.077s
user 0m0.457s
sys 0m0.156s
$ cp /tmp/foo /tmp/foo1 && time popline /tmp/foo1
*/
real 0m0.052s
user 0m0.002s
sys 0m0.003s
답변2
목표는 하나의 명령을 사용하여 파일의 마지막 줄을 출력하는 동시에 원본 파일에서 해당 줄을 제거하는 것입니다.
sed -i -e '${w /dev/stdout' -e 'd;}' file
그러면 다음 sed
스크립트가 실행됩니다.
${
w /dev/stdout
d
}
마지막 줄을 쓴 /dev/stdout
다음 삭제합니다. 다른 모든 행은 이 옵션을 사용하여 원본 파일에 다시 기록됩니다 -i
.
명령의 출력 파일 이름을 분리할 수 있는 다른 방법이 없기 때문에 w
(리터럴 개행 문자를 삽입하는 것 외에) 명령줄의 스크립트는 두 부분으로 분할되어야 합니다.
그리고 ed
:
ed -s file <<END_ED
p
d
w
END_ED
ed
파일을 열고 file
파일의 마지막 줄에 커서를 놓습니다. 첫 번째 명령은 행을 표준 출력으로 인쇄하고, 두 번째 명령은 이를 삭제하고, 마지막 명령은 버퍼를 파일에 다시 씁니다. 대용량 파일에는 권장되지 않습니다 ed
.