sed를 사용하여 대용량 파일 헤더를 효율적으로 제거하시겠습니까?

sed를 사용하여 대용량 파일 헤더를 효율적으로 제거하시겠습니까?

다음 명령은 파일 크기에 따라 몇 분 정도 걸릴 수 있습니다. 더 효율적인 방법이 있나요?

sed -i 1d large_file 

답변1

다음으로 변경해 보세요 ed.

ed <<< $'1d\nwq' large_file

"큰"이 약 1천만 행 이상을 의미하는 경우 를 사용하는 것이 더 좋습니다 tail. 내부 편집은 불가능하지만 성능상 이러한 결함은 용서할 수 있습니다.

tail -n +2 large_file > large_file.new

편집하다몇 가지 시차를 표시합니다.

( awkJaypal이 추가한 코드는 동일한 머신(CPU 2.2GHz)에서 실행 시간이 있습니다.)

bash-4.2$ seq 1000000 > bigfile.txt # further file creations skipped

bash-4.2$ time sed -i 1d bigfile.txt
time 0m4.318s

bash-4.2$ time ed -s <<< $'1d\nwq' bigfile.txt
time 0m0.533s

bash-4.2$ time perl -pi -e 'undef$_ if$.==1' bigfile.txt
time 0m0.626s

bash-4.2$ time { tail -n +2 bigfile.txt > bigfile.new && mv -f bigfile.new bigfile.txt; }
time 0m0.034s

bash-4.2$ time { awk 'NR>1 {print}' bigfile.txt > newfile.txt && mv -f newfile.txt bigfile.txt; }
time 0m0.328s

답변2

파일 시작 부분에서 콘텐츠를 효율적으로 제거할 수 있는 방법은 없습니다. 데이터를 처음부터 삭제하려면 전체 파일을 다시 작성해야 합니다.

하지만 파일 끝부터 자르는 작업은 매우 빠릅니다. (운영 체제는 단순히 파일 크기 정보를 조정하여 현재 사용하지 않는 블록을 지울 수도 있습니다.) 파일의 헤드에서 삭제하려고 하면 일반적으로 불가능합니다.

전체 블록/범위를 정확하게 삭제하면 이론적으로는 "빠를" 수 있지만 시스템 호출이 없으므로 파일 시스템별 의미가 있는 경우 이에 의존해야 합니다. (또는 파일의 실제 시작을 표시하기 위해 첫 번째 블록/범위 내에 어떤 형태의 오프셋이 있을 것 같습니다. 그것도 들어본 적이 없습니다.)

답변3

가장 효과적인 방법은 하지 않는 것입니다! 이렇게 하면 어쨌든 두 배의 "큰" 디스크 공간이 필요하고 IO를 낭비하게 됩니다.

큰 파일을 발견하고 첫 번째 줄 없이 파일을 읽으려면 읽어야 할 때까지 기다렸다가 첫 번째 줄을 제거하세요. stdin에서 프로그램으로 파일을 보내려면 tail을 사용하십시오.

tail -n +2 | your_program

파일을 읽어야 할 경우 첫 번째 줄을 삭제할 수 있지만 디스크에 필요한 공간이 있는 경우에만 가능합니다.

tail -n +2 | tee large_file2 | your_program

stdin에서 데이터를 읽을 수 없으면 fifo를 사용하십시오.

mkfifo large_file_wo_1st_line
tail -n +2 large_file > large_file_wo_1st_line&
your_program -i large_file_wo_1st_line

bash를 사용하는 경우 프로세스 대체를 활용하는 것이 더 좋습니다.

your_program -i <(tail -n +2 large_file)

파일에서 찾아야 할 경우, 애초에 파일에 갇혀 있는 것보다 더 나은 해결책은 없다고 생각합니다. 파일이 stdout에서 생성된 경우:

large_file_generator | tail -n +2 > large_file

그렇지 않으면 항상 fifo 또는 프로세스 교체 솔루션이 있습니다.

mkfifo large_file_with_1st_file
large_file_generator -o large_file_with_1st_file&
tail -n +2 large_file_with_1st_file > large_file_wo_1st_file

large_file_generator -o >(tail -n 2+ > large_file_wo_1st_file)

답변4

이건 이론일 뿐이지만...

사용자 정의 파일 시스템(FUSE 또는 유사한 메커니즘을 사용하여 구현됨)은 내용이 다른 곳에 이미 존재하는 디렉토리와 정확히 동일하지만 원하는 대로 파일이 잘린 디렉토리를 노출할 수 있습니다. 파일 시스템은 모든 파일 오프셋을 변환합니다. 이렇게 하면 시간이 많이 걸리는 파일 다시 쓰기를 수행할 필요가 없습니다.

그러나 이러한 파일이 수십 테라바이트에 달하지 않는 한 이러한 파일 시스템을 구현하는 것은 너무 비싸고 시간이 많이 걸려 실용적이지 않다는 점을 고려하는 것이 중요합니다.

관련 정보