줄 순서를 바꾸지 않아도되고 GNU coreutils가있는 경우 (즉, shuf
버전 6.0에 등장한 이후로 너무 오래되지 않은 내장되지 않은 Linux 또는 Cygwin )shuf
(“셔플”)은 파일의 줄을 무작위로 다시 정렬합니다. 따라서 파일을 섞어서 첫 번째 m 행을 한 파일로, 나머지 m 행을 다른 파일로 발송할 수 있습니다.
그 파견을 수행하는 이상적인 방법은 없습니다. 당신은 체인을 할 수 없습니다 head
하고 tail
있기 때문에 head
앞으로 버퍼 것입니다. 을 사용할 수 split
있지만 출력 파일 이름과 관련하여 유연성을 얻지 못합니다. awk
물론 사용할 수 있습니다 :
<input shuf | awk -v m=$m '{ if (NR <= m) {print >"output1"} else {print} }'
을 사용할 수 있습니다 sed
.이 기능은 애매하지만 큰 파일에는 더 빠릅니다.
<input shuf | sed -e "1,${m} w output1" -e "1,${m} d" >output2
또는 tee
플랫폼에 데이터가있는 경우 데이터를 복제하는 데 사용할 수 있습니다 /dev/fd
. m이 작 으면 괜찮습니다.
<input shuf | { tee /dev/fd/3 | head -n $m >output1; } 3>&1 | tail -n +$(($m+1)) >output2
awk를 사용하여 각 줄을 차례로 전달할 수 있습니다. awk는 난수 생성기를 초기화하는 데별로 좋지 않습니다. 무작위성은 암호화에 적합하지 않을뿐만 아니라 수치 시뮬레이션에도 적합하지 않습니다. 시드는 1 초의 기간이있는 시스템에서 모든 awk 호출에 대해 동일합니다.
<input awk -v N=$(wc -l <input) -v m=3 '
BEGIN {srand()}
{
if (rand() * N < m) {--m; print >"output1"} else {print >"output2"}
--N;
}'
더 나은 무작위성이 필요한 경우 Perl에서 동일한 작업을 수행하여 RNG를 적절하게 시드 할 수 있습니다.
<input perl -e '
open OUT1, ">", "output1" or die $!;
open OUT2, ">", "output2" or die $!;
my $N = `wc -l <input`;
my $m = $ARGV[0];
while (<STDIN>) {
if (rand($N) < $m) { --$m; print OUT1 $_; } else { print OUT2 $_; }
--$N;
}
close OUT1 or die $!;
close OUT2 or die $!;
' 42