데이터 파일에서 임의의 수의 라인 그리기

데이터 파일에서 임의의 수의 라인 그리기

다음과 같은 데이터 목록이 있습니다.

12345
23456
67891
-20000
200
600
20
...

이 데이터 세트(즉, 파일 행)의 크기가 N. m이 데이터 파일에서 임의의 선을 그리고 싶습니다 . 따라서 출력은 두 개의 파일이어야 합니다. 하나는 이러한 m데이터 행을 포함하고 다른 하나는 이러한 N-m데이터 행을 포함합니다.

Linux 명령을 사용하여 이를 수행할 수 있는 방법이 있습니까?

답변1

이는 가장 효율적인 접근 방식은 아니지만 다음과 같이 작동합니다.

shuf <file> > tmp
head -n $m tmp > out1
tail -n +$(( m + 1 )) tmp > out2

$m행 수를 포함합니다 .

답변2

이 bash/awk 스크립트는 행을 무작위로 선택하고 두 개의 출력 파일에서 원래 순서를 유지합니다.

awk -v m=4 -v N=$(wc -l <file) -v out1=/tmp/out1 -v out2=/tmp/out2 \
 'BEGIN{ srand()
         do{ lnb = 1 + int(rand()*N)
             if ( !(lnb in R) ) {
                 R[lnb] = 1
                 ct++ }
         } while (ct<m)
  } { if (R[NR]==1) print > out1 
      else          print > out2       
  }' file
cat /tmp/out1
echo ========
cat /tmp/out2

질문의 데이터를 기반으로 한 출력입니다.

12345
23456
200
600
========
67891
-20000
20

답변3

Unix의 모든 것과 마찬가지로 Utility for That TM이 있습니다 .

오늘의 프로그램: split
split파일을 다양한 방법, -b바이트, -l줄, -n출력 파일 수로 분할합니다. 우리는 이 옵션을 사용할 것입니다 -l. 첫 번째 행뿐만 아니라 임의의 행을 선택하려고 하므로 파일을 무작위로 선택하는 것부터 시작합니다 m. sort이에 대해 알고 싶다면 sort내 답변을 참조하십시오.여기.

이제 실제 코드입니다. 정말 간단합니다.

sort -R input_file | split -l $m output_prefix

이렇게 하면 두 개의 파일이 생성됩니다. 하나는 m행을 포함하고 다른 하나는 및 N-m이름의 행을 포함합니다. 원하는 파일이 더 큰지 확인하세요 . 그렇지 않으면 같은 길이의 여러 파일 (하나는 )이 생성됩니다.output_prefixaaoutput_prefixabmmN % m

올바른 치수를 사용하고 있는지 확인하려면 다음 코드를 사용하세요.

m=10 # size you want one file to be
N=$(wc -l input_file)
m=$(( m > N/2 ? m : N - m ))
sort -R input_file | split -l $m output_prefix

편집: 일부 구현에는 플래그가 sort없는 것으로 나타났습니다 . -R가능한 경우 perl교체할 수 있습니다 perl -e 'use List::Util qw/shuffle/; print shuffle <>;'.

답변4

가정 m = 7하고 N = 21:

cp ints ints.bak
for i in {1..7}
do
    rnd=$((RANDOM%(21-i)+1))
    # echo $rnd;  
    sed -n "${rnd}{p,q}" 10k.dat >> mlines 
    sed -i "${rnd}d" ints 
done

참고: 또는 와 같은 변수를 대체하는 경우 7대신 변수 확장을 수행하지 않는 - 표기법을 사용해야 합니다.$1$mseq{from..to}

파일에서 한 줄씩 삭제하는 방식으로 작동하는데, 파일이 점점 짧아지므로 삭제할 수 있는 줄 번호도 점점 작아져야 합니다.

긴 파일과 많은 줄에는 사용하면 안 됩니다. 각 숫자에 대해 평균적으로 첫 번째 파일은 파일의 절반을 읽어야 하고 두 번째 파일은 전체 파일을 읽어야 하기 때문입니다.sed암호.

관련 정보