Existem dois motivos. Em primeiro lugar, você não diz para q
uit.
Considere:
seq 10 | sed -ne1,5p
Nesse caso, embora apenas p
rints a primeira metade das linhas de entrada, ele ainda deve ler o resto delas até EOF. Em vez disso:
seq 10|sed 5q
Ele sairá imediatamente.
Você também está trabalhando com um atraso entre cada processo. Então se pv
buffers em 4kb, e sed
buffers 4kb, então o último pv
é 8kb atrás da entrada o tempo todo. É bem provável que os números sejam maiores que isso.
Você pode tentar a opção -u
com GNU / BSD / AST sed
, mas é quase certo que não irá ajudar o desempenho em grandes entradas.
Se você chamar um GNU sed
com -u
, será read()
para cada byte de entrada. Não olhei para o que os outros fazem nessa situação, mas não tenho motivos para acreditar que eles fariam algo diferente. Todos os três documentos -u
significam unbuffered - e esse é um conceito bastante comumente entendido no que diz respeito aos fluxos.
Outra coisa que você pode fazer é explicitamente a saída do sed
do line-buffer com o comando w
rite e um ou mais nomes w
rite-file [s]. Isso ainda vai atrasar um pouco as coisas, mas provavelmente será melhor que a alternativa.
Você pode fazer isso com qualquer sed
como:
sed -n 'w outfile'
O comando sed
rite do w
é sempre imediato - é uma saída sem buffer. E como (por padrão) sed
aplica os comandos uma vez por ciclo de linha, sed
pode ser facilmente usado para efetivamente efetuar o i / o de buffer de linha mesmo no meio de um pipeline. Dessa forma, pelo menos, você pode manter o segundo pv
praticamente atualizado com sed
o tempo todo como:
pv ... | sed -n '24629045,24629162!w /dev/fd/1' | pv ...
... embora isso pressuponha um sistema que forneça os /dev/fd/[num]
links (o que quer dizer: praticamente qualquer sistema baseado em linux - exceto Android - e muitos outros além ) . Falha na disponibilidade dos links, para fazer a mesma coisa você pode simplesmente criar explicitamente seu próprio pipe com mkfifo
e usá-lo como o último stdin de pv
e nomeá-lo como sed
' w
rite file.