Se você sabe o número de linhas no arquivo (como 1e6 no seu caso), você pode fazer:
awk -v n=1e6 -v p=1000 '
BEGIN {srand()}
rand() * n-- < p {p--; print}' < file
Se não, você sempre pode fazer
awk -v n="$(wc -l < file)" -v p=1000 '
BEGIN {srand()}
rand() * n-- < p {p--; print}' < file
Isso faria duas passagens no arquivo, mas ainda evitaria armazenar todo o arquivo na memória.
Outra vantagem sobre o GNU shuf
é que ele preserva a ordem das linhas no arquivo.
Observe que ele assume n
é o número de linhas no arquivo. Se você quiser imprimir p
das primeiras n
linhas do arquivo (que tem potencialmente mais linhas), será necessário interromper awk
no n
sup > th linha como:
awk -v n=1e6 -v p=1000 '
BEGIN {srand()}
rand() * n-- < p {p--; print}
!n {exit}' < file