출력을 작성한 후 sed가 즉시 종료되지 않는 이유는 무엇입니까?

출력을 작성한 후 sed가 즉시 종료되지 않는 이유는 무엇입니까?

나는 큰 파일에서 sed를 실행하고 있으며PV입력을 읽고 출력을 쓰는 속도를 확인하는 유틸리티입니다. pv는 약 5초 안에 sed가 입력을 읽고 출력을 쓰는 것을 보여주지만, sed는 20~30초 동안 종료되지 않습니다. 왜 이런거야?

내가 본 결과는 다음과 같습니다.

pv -cN source input.txt | sed "24629045,24629162d" | pv -cN output > output.txt
   source: 2.34GB 0:00:06 [ 388MB/s] [==========================================================================================================>] 100%            
   output: 2.34GB 0:00:05 [ 401MB/s] [              <=>                                                                                                           ]

답변1

두 가지 이유가 있습니다. 우선, 당신은 그것을 말하지 않았습니다 q.

고려하다:

seq 10 | sed -ne1,5p

이 경우 p입력 라인의 첫 번째 절반만 인쇄하지만 EOF까지 입력 라인의 나머지 부분을 읽어야 합니다. 대신에:

seq 10|sed 5q

즉시 종료됩니다.

또한 각 프로세스 간의 대기 시간도 처리해야 합니다. 따라서 pv4kb에서 버퍼링하고 sed4kb를 버퍼링하는 경우 마지막 버퍼는 pv항상 입력보다 8kb 뒤쳐집니다. 그 수치는 그보다 훨씬 높을 가능성이 높습니다.

-uGNU/BSD/AST를 사용하여 전환 해 볼 수도 있지만 sed이는 거의 확실합니다.아니요대규모 입력의 성능을 향상시키는 데 도움이 됩니다. 이를 사용하여 sedGNU를 호출 하면 입력의 모든 바이트를 대상으로 -u합니다 read(). 나는 이 상황에서 다른 사람이 어떻게 할지 본 적이 없지만 그들이 다르게 행동할 것이라고 믿을 이유가 없습니다. 세 파일 모두의 -u의미버퍼링되지 않은- 이것은 스트림과 관련하여 매우 일반적으로 이해되는 개념입니다.

당신이 할 수 있는 또 다른 일은 명시적인 line-buffer 입니다 sed.산출write 명령과 하나 이상의 명명된 write-file[s]을 사용합니다 . 여전히 속도는 느려지지만 대안보다 나을 수 있습니다.

sed다음과 같은 방법으로 이 작업을 수행 할 수 있습니다 .

sed -n 'w outfile'

sedrite w명령은 항상 즉각적입니다. 버퍼링되지 않은 출력이 있습니다. 때문에(기본적으로) sed행 주기당 한 번 명령을 적용하면 sed파이프라인 도중에도 효율적인 행 버퍼링 I/O를 쉽게 사용할 수 있습니다. 이렇게 하면 최소한 다음 과 같이 pv두 번째 항목을 항상 최신 상태로 유지할 수 있습니다 sed.

pv ... | sed -n '24629045,24629162!w /dev/fd/1' | pv ...

/dev/fd/[num]...링크를 제공하는 시스템이 있다고 가정하더라도(즉, Android를 제외한 거의 모든 Linux 기반 시스템 및다른 많은 것들이 있습니다). 해당 링크를 사용할 수 없는 경우 동일한 작업을 수행하려면 명시적으로 자신만의 파이프를 생성 mkfifo하고 이를 마지막 rite 파일 pv의 표준 입력 으로 사용할 수 있습니다 .sedw

관련 정보