यदि आपको लाइनों को रीक्रिएट करने में कोई आपत्ति नहीं है और आपके पास GNU कोरूटिल्स हैं (यानी नॉन-एम्बेडेड लिनक्स या साइगविन पर, shuf
संस्करण 6.0 में दिखाई देने के बाद भी प्राचीन नहीं हैं ), shuf
("फेरबदल") किसी फ़ाइल की लाइनों को अनियमित रूप से पुन: व्यवस्थित करता है। तो आप फ़ाइल को फेरबदल कर सकते हैं और पहली 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 अपने यादृच्छिक संख्या जनरेटर को शुरू करने में बहुत अच्छा नहीं है; यादृच्छिकता न केवल क्रिप्टोग्राफी के लिए उपयुक्त है, बल्कि संख्यात्मक सिमुलेशन के लिए भी बहुत अच्छी नहीं है। बीज एक सेकंड की अवधि के साथ किसी भी सिस्टम पर सभी awk invocations के लिए समान होगा।
<input awk -v N=$(wc -l <input) -v m=3 '
BEGIN {srand()}
{
if (rand() * N < m) {--m; print >"output1"} else {print >"output2"}
--N;
}'
यदि आपको बेहतर यादृच्छिकता की आवश्यकता है, तो आप पर्ल में वही काम कर सकते हैं, जो इसके आरएनजी को शालीनता से बीज देता है।
<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