'nl' invocação absorvendo toda a entrada antes da numeração

1

Como isso pode ser feito?

Não vejo nenhuma opção aplicável no manual.

Eu verifiquei positivamente que recuo quebra após dez milhões de linhas.

Você pode ver como:

$ (for i in 'seq 0 10000000'; do echo "$i"; done) | nl

Eu não costumo gerar tantas linhas, mas não quero que ele quebre como acontece. Como isso pode ser feito?

    
por uprego 14.01.2015 / 11:53

2 respostas

4

Se você estiver sugerindo que nl deve armazenar em buffer toda a entrada simplesmente para medir o número máximo necessário, isso não está no espírito dos filtros de fluxo. Com raras exceções ( sort , por exemplo), os principais utilitários tentam processar fluxos imediatamente - especialmente porque podem ser usados em um pipeline virtualmente infinito (por exemplo, um fluxo de log que é incrementalmente filtrado por nl e redirecionado para um arquivo pode acumular muitos dados).

A maneira padrão de lidar com preenchimento é simplesmente especificar a largura máxima esperada como um parâmetro. Nesse caso, você pode desativar o preenchimento (prefiro isso de qualquer maneira, faz sentido ter apenas uma coluna separada por espaço na frente) ou definir uma largura diferente. Comparar:

seq 0 10000000 | nl -w12 # default right-justify, 12 character width

seq 0 10000000 | nl -w1 # default right-justify, 1 character width (no padding)

seq 0 10000000 | nl -w1 -s' ' # right-justify, space delimited instead of tab

seq 0 10000000 | nl -nln # left-justify

Se você realmente quiser fazer isso automaticamente, basta usar wc -l para primeiro medir o comprimento e depois definir o -w apropriadamente.

    
por 14.01.2015 / 16:04
1

O seq 0 10000000 está se expandindo para dez milhões e uma linha, que bash precisa armazenar em sua memória para poder fazer um loop sobre os valores. Que é o que quebra, eu consegui terminá-lo antes que ele usasse toda a memória + swap no meu sistema (eu não queria que a falta de memória matasse algum outro processo, apesar dos kernels modernos irá determinar corretamente qual processo matar).

Você pode verificar se não é nl substituindo nl por cat ou wc ou qualquer outro comando que leia sua entrada.

A versão de muru deve ser equivalente sem exigir que bash armazene todos esses dados de maneira intermediária.

EDIT: se for sobre o preenchimento do número, eu esperaria que uma leitura de 10 segundos da manpage levaria à opção nl -w ... Use nl -w8 . Se você estiver insatisfeito com a grande lacuna entre o número da linha e o conteúdo da linha (devido à guia padrão sendo usada), você pode adicionar -s' ' ; está tudo lá na manpage, facilmente encontrado. Eu ainda estou me perguntando por que o loop for na questão embora.

    
por 14.01.2015 / 14:51