파일의 한 줄을 팝(읽기 및 삭제)하는 방법은 무엇입니까?

파일의 한 줄을 팝(읽기 및 삭제)하는 방법은 무엇입니까?

파일의 마지막 줄을 가져온 다음 삭제하려고 합니다.

다음 줄을 읽어보세요:

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.

관련 정보