2014-03-05 1 views
2

설정 :는 같은 순서로 여러 파일을 셔플

내가 50 개 파일, 25000 선을 각각 가지고있다.

는 할 일 :

나는 "같은 순서로"모두 셔플해야합니다. 예컨대 : 셔플 전에

경우 :

File 1 File 2 File 3 
A  A  A 
B  B  B 
C  C  C 

는 셔플 후에 내가 가야 :

File 1 File 2 File 3 
B  B  B 
C  C  C 
A  A  A 

은 즉 파일의 해당 행은 같은 순서로 단행해야한다.

또한 셔플은 결정적이어야합니다. 즉, 파일 A를 입력으로 제공하면 항상 동일한 동일한 출력을 생성해야합니다.

내가 할 수있는 Java 프로그램을 작성할 수 있습니다. 뭔가를 좋아하고, 1에서 25000 사이의 숫자를 섞어서 파일에 저장하십시오, 예를 들어 shuffle_order. 그런 다음 한 번에 하나의 파일을 처리하고 shuffle_order에 따라 기존 행을 정렬합니다. 그러나 이것을하기위한 더 나은/빠른 방법이 있습니까?

자세한 정보가 필요하면 알려주십시오.

+0

너 큰 문제 야. ay는 아직 눈치 채지 못했습니다.) 하나의 파일을 미리 정해진 순서대로 저장하는 방법입니다. 특히 한 번에 전체 파일을 메모리에 저장할 수 있다고 가정 할 수없는 경우에 특히 그렇습니다."중간"파일을 만들어야 할 수도 있습니다 (각 줄은 줄 앞에 접두어가 붙습니다). 그런 다음 파일을 마침내 순서대로 가질 때까지 ping/pong 모드의 파일을 통과해야합니다. – ErstwhileIII

+0

"파일이 메모리에 맞지 않습니다"를 처리해야하는 경우 질문을 조정하고 "병합 정렬"프로세스에 대한 제안을 드릴 수 있습니다. – ErstwhileIII

답변

0

아마 매우 비효율적하지만 아래 시도 :

#!/bin/bash 

arr=($(for i in {1..25000}; do 
    echo "$i" 
done | shuf)) 


for file in files*; do 
    index=0 
    new=$(while read line; do 
     echo "${arr[$index]} $line" 
     ((index++)) 
    done < "$file" | sort -h | sed 's/^[0-9]\+ //') 
    echo "$new" > "$file" 
done 
1

다음 사용하는 기본적인 bash는 명령을. 프린은 다음과 같습니다

A B C 
-------- 
a1 a2 a3 
b1 b2 b3 
c1 c2 c3 
d1 d2 d3 
e1 e2 e3 
f1 f2 f3 
g1 g2 g3 
h1 h2 h3 
i1 i2 i3 
j1 j2 j3 
:

  • 는 임의의 순서 (번호)
  • 순서를 생성 순서

코드 입력 파일에서

#!/bin/bash 
case "$#" in 
    0) echo "Usage: $0 files....." ; exit 1;; 
esac 

ORDER="./.rand.$$" 
trap "rm -f $ORDER;exit" 1 2 
count=$(grep -c '^' "$1") 

let odcount=$(($count * 4)) 
paste -d" " <(od -A n -N $odcount -t u4 /dev/urandom | grep -o '[0-9]*') <(seq -w $count) |\ 
    sort -k1n | cut -d " " -f2 > $ORDER 

#if your system has the "shuf" command you can replace the above 3 lines with a simple 
#seq -w $count | shuf > $ORDER 

for file in "[email protected]" 
do 
    paste -d' ' $ORDER $file | sort -k1n | cut -d' ' -f2- > "$file.rand" 
done 

echo "the order is in the file $ORDER" # remove this line 
#rm -f $ORDER       # and uncomment this 
             # if dont need preserve the order 

paste -d " " *.rand #remove this line - it is only for showing test result 

에있는 모든 파일

은다음 예제의 내용 337,845,532,659,771,143,210

g1 g2 g3 
e1 e2 e3 
b1 b2 b3 
c1 c2 c3 
f1 f2 f3 
j1 j2 j3 
d1 d2 d3 
h1 h2 h3 
i1 i2 i3 
a1 a2 a3 

실제 시험 - 내 노트북의 스크립트

bash sorter.sh file.?? 

결과를 실행 25K 라인

line="Consequatur qui et qui. Mollitia expedita aut excepturi modi. Enim nihil et laboriosam sit a tenetur." 
for n in $(seq -w 50) 
do 
    seq -f "$line %g" 25000 >file.$n 
done 

50 개 파일을 genereting

real  1m13.404s 
user  0m56.127s 
sys  0m5.143s