[bash] 파일에서 임의의 줄을 선택하십시오

Bash 스크립트에서 입력 파일에서 N 개의 임의 행을 골라 다른 파일로 출력하고 싶습니다.

어떻게 할 수 있습니까?



답변

임의의 행 을 얻으려면 아래 표시된 옵션과 shuf함께 사용하십시오 .-nN

shuf -n N input > output


답변

파일을 무작위로 정렬하고 첫 번째 100줄을 선택하십시오 .

$ sort -R input | head -n 100 >output


답변

shuf 답변에 대한 의견에 따르면 그는 1 분 안에 78 000 000 000 라인을 uff습니다.

챌린지 허용 …

편집 : 나는 내 자신의 기록을 이겼다

powershuf는 0.047 초 안에 그것을했다

$ time ./powershuf.py -n 10 --file lines_78000000000.txt > /dev/null
./powershuf.py -n 10 --file lines_78000000000.txt > /dev/null  0.02s user 0.01s system 80% cpu 0.047 total

너무 빠르기 때문에 전체 파일을 읽지 않고 파일 포인터를 10 번 이동하고 포인터 뒤에 줄을 인쇄하십시오.

깃랩 레포

오래된 시도

먼저 78.000.000.000 줄의 파일이 필요했습니다.

seq 1 78 | xargs -n 1 -P 16 -I% seq 1 1000 | xargs -n 1 -P 16 -I% echo "" > lines_78000.txt
seq 1 1000 | xargs -n 1 -P 16 -I% cat lines_78000.txt > lines_78000000.txt
seq 1 1000 | xargs -n 1 -P 16 -I% cat lines_78000000.txt > lines_78000000000.txt

이것은 78 억의 파일을 제공합니다. 바꿈이있는 😉

이제 shuf 부분에 대해 :

$ time shuf -n 10 lines_78000000000.txt










shuf -n 10 lines_78000000000.txt  2171.20s user 22.17s system 99% cpu 36:35.80 total

병목 현상은 CPU이며 여러 스레드를 사용하지 않고 100 %에서 1 코어를 고정하고 다른 15 개는 사용하지 않았습니다.

파이썬은 내가 정기적으로 사용하는 것이므로 이것을 더 빨리 만들기 위해 사용할 것입니다.

#!/bin/python3
import random
f = open("lines_78000000000.txt", "rt")
count = 0
while 1:
  buffer = f.read(65536)
  if not buffer: break
  count += buffer.count('\n')

for i in range(10):
  f.readline(random.randint(1, count))

이것은 1 분 안에 나를 얻었습니다.

$ time ./shuf.py










./shuf.py  42.57s user 16.19s system 98% cpu 59.752 total

필자는 i9 및 Samsung NVMe와 함께 Lenovo X1 익스트림 2 세대에서이 작업을 수행하여 읽기 및 쓰기 속도를 크게 향상 시켰습니다.

나는 그것이 더 빨라질 수 있다는 것을 알고 있지만 다른 사람들이 시도해 볼 수있는 공간을 남겨 둘 것입니다.

라인 카운터 소스 : Luther Blissett


답변