मैं Red Hat Linux पर मानक टूल का उपयोग करके किसी फ़ाइल में लाइनों को कैसे यादृच्छिक कर सकता हूँ?


102

मैं Red Hat Linux पर मानक टूल का उपयोग करके किसी फ़ाइल में लाइनों को कैसे यादृच्छिक कर सकता हूँ?

मेरे पास shufकमांड नहीं है , इसलिए मैं एक perlया awkएक-लाइनर की तरह कुछ ढूंढ रहा हूं जो समान कार्य को पूरा करता है।


1
मैंने लगभग एक ही सवाल पूछा [ stackoverflow.com/questions/286640/…
स्टीव श्नेप


मैं किसी भी linux में gcc को एक मानक उपकरण मानता हूँ। ; डी
एमएसबी

जवाबों:


64

और एक पर्ल एक लाइनर आपको मिलता है!

perl -MList::Util -e 'print List::Util::shuffle <>'

यह एक मॉड्यूल का उपयोग करता है, लेकिन मॉड्यूल पर्ल कोड वितरण का हिस्सा है। यदि यह पर्याप्त अच्छा नहीं है, तो आप अपना स्वयं का रोल करने पर विचार कर सकते हैं।

मैंने -iध्वज ("एड-इन-प्लेस") के साथ इसका उपयोग करने की कोशिश की, ताकि यह फ़ाइल को संपादित कर सके। प्रलेखन का सुझाव है कि यह काम करना चाहिए, लेकिन यह नहीं है। यह अभी भी stfout में फेरबदल फ़ाइल प्रदर्शित करता है, लेकिन इस बार यह मूल को हटा देता है। मेरा सुझाव है कि आप इसका उपयोग न करें।

एक शेल स्क्रिप्ट पर विचार करें:

#!/bin/sh

if [[ $# -eq 0 ]]
then
  echo "Usage: $0 [file ...]"
  exit 1
fi

for i in "$@"
do
  perl -MList::Util -e 'print List::Util::shuffle <>' $i > $i.new
  if [[ `wc -c $i` -eq `wc -c $i.new` ]]
  then
    mv $i.new $i
  else
    echo "Error for file $i!"
  fi
done

निष्कलंक, लेकिन उम्मीद है कि काम करता है।


मूल फ़ाइल का बैकअप लेने के लिए, आप -i ध्वज [ perldoc.perl.org/perlrun.html] के
स्टीव श्नाइप

मैं आमतौर पर एक पर्ल फैन हूं, लेकिन इस रूबी उदाहरण के सामने आया जिसका लाभ कम होने का है ruby -e 'puts STDIN.readlines.shuffle':। यह देखने के लिए बड़े इनपुट पर परीक्षण की आवश्यकता होगी कि क्या गति तुलनीय है। (OS X पर भी काम करता है)
works

प्रति टिप्पणी नीचे दी गई है, shufसब कुछ स्मृति में लोड करता है, इसलिए यह वास्तव में बहुत बड़ी फ़ाइल के साथ काम नहीं करता है (मेरा ~ 300GB tsv है)। यह पर्ल स्क्रिप्ट मेरी भी असफल रही, लेकिन कोई त्रुटि के अलावा Killed। किसी भी विचार अगर perl समाधान सब कुछ स्मृति में भी लोड हो रहा है, या वहाँ कुछ और समस्या है जिसका मैं सामना कर रहा हूँ?
seth127

211

उम, भूलने नहीं देता

sort --random-sort

1
खैर, मैं gnu-coreutils 7.1 (मानक gentoo इनस्टॉल) का उपयोग कर रहा हूँ, जो इस विकल्प के साथ क्रमित है, निश्चित नहीं है कि यह कब दिखाई दिया, या यदि यह अन्य कार्यान्वयन में है।
जिम टी

1
यह सुविधा 10 दिसंबर 2005 को जारी की गई थी, जिसके बाद रिलीज़ की अवधि 5.94 थी, इसलिए मुझे लगता है कि यह उस संस्करण के बाद से उपलब्ध है।
जिम टी

41
ओएस एक्स पर आप होमब्रे के साथ ग्नू कोरटिल्स स्थापित कर सकते हैं: brew install coreutilsसभी बर्तनों को एजी के साथ उपसर्ग किया जाता है: gsort --random-sortया gshufअपेक्षित रूप से काम करेगा
माइक

3
+1 @ माइक। मैं मैकपोर्ट्स का उपयोग करता हूं और मैंने भी किया था gsortऔर gshufजब मैंने किया था तब स्थापित किया थाport install coreutils
नूह सुस्मान

10
यह समाधान केवल तभी अच्छा है जब आपकी लाइनों में पुनरावृत्ति न हो। यदि वे करते हैं, तो उस रेखा के सभी उदाहरण एक-दूसरे के बगल में दिखाई देंगे। shufइसके बजाय (linux पर) का उपयोग करने पर विचार करें ।
अली जे

118

shuf सबसे अच्छा तरीका है।

sort -Rदर्द धीमा है। मैंने अभी 5GB फ़ाइल को सॉर्ट करने की कोशिश की है। मैंने 2.5 घंटे के बाद त्याग दिया। फिर shufएक मिनट में हल कर दिया।


यह भी खूब रही। यह GNU कोरुटिल्स में प्रतीत होता है।

4
मुझे संदेह है कि कारण sort -Rधीमा है जो प्रत्येक पंक्ति के लिए एक हैश की गणना करता है। डॉक्स से: " इनपुट कुंजियों को हैशिंग से सॉर्ट करें और फिर हैश वैल्यू को सॉर्ट करें। "
जो फ्लिन

13
खबरदार, shufसब कुछ स्मृति में लोड करता है।
JFS

1
@benroth: मैं जो कुछ भी बता सकता हूं उससे बड़े इनपुट के साथ मेमोरी बढ़ाने में कुछ हद तक मदद मिल सकती है , लेकिन यह अभी भी कुल मिलाकर धीमा है। मेरे परीक्षणों में, बनाई गई 1-मिलियन-लाइन इनपुट फ़ाइल को सॉर्ट करने के लिए एक seq -f 'line %.0f' 1000000ही, लंबे समय से संसाधित करने के लिए (बहुत अधिक, अब की तुलना में shuf), चाहे मुझे कितनी भी स्मृति आवंटित की गई हो।
mklement0

1
@ mklement0, आप सही कह रहे हैं! मैंने इसे पहले की तुलना में बहुत बड़ी फ़ाइल के साथ आज़माया, और हैशिंग वास्तव में अड़चन है।
benroth

23
cat yourfile.txt | while IFS= read -r f; do printf "%05d %s\n" "$RANDOM" "$f"; done | sort -n | cut -c7-

फ़ाइल पढ़ें, एक यादृच्छिक संख्या के साथ हर पंक्ति को प्रीपेन्ड करें, उन यादृच्छिक उपसर्गों पर फ़ाइल को सॉर्ट करें, बाद में उपसर्गों को काटें। वन-लाइनर जो किसी भी अर्ध-आधुनिक शेल में काम करना चाहिए।

EDIT: रिचर्ड हैनसेन की टिप्पणियों को शामिल किया गया।


1
यह काम करता है, और एक रचनात्मक समाधान है, लेकिन लाइनों पर प्रमुख व्हाट्सएप को हटा देगा।
क्रिस लुत्ज

@ क्रिस अंतिम कट को बदल रहा है। sed 's / ^ [^ \ t] * \ t //' को ठीक करना चाहिए
bdonlan

दृष्टिकोण की सादगी के लिए यश!
शशिकांत कोरे

3
POSIX अनुरूपता के लिए +1 ( $RANDOMडेटा को छोड़कर ), लेकिन डेटा को ब्रीच करने के लिए -1। के while read fसाथ प्रतिस्थापित करने से अग्रणी और अनुगामी व्हाट्सएप ( इस उत्तर को देखें ) को हटाने से while IFS= read -r fरोका readजा सकेगा और बैकस्लैश के प्रसंस्करण को रोका जा सकेगा । एक निश्चित-लंबाई वाले यादृच्छिक स्ट्रिंग का उपयोग करने से प्रमुख व्हाट्सएप को हटाने से रोका जा सकेगा । परिणाम: cutcat yourfile.txt | while IFS= read -r f; do printf "%05d %s\n" "$RANDOM" "$f"; done | sort -n | cut -c7-
रिचर्ड हैनसेन

3
@ रीचर्ड हैनसेन: धन्यवाद, ये सुझाए गए बदलाव स्पष्ट रूप से उचित हैं, मैंने अपनी पोस्ट संपादित की है।
क्रिस्टोफ़ीड

9

अजगर के लिए एक लाइनर:

python -c "import random, sys; lines = open(sys.argv[1]).readlines(); random.shuffle(lines); print ''.join(lines)," myFile

और मुद्रण के लिए सिर्फ एक यादृच्छिक लाइन:

python -c "import random, sys; print random.choice(open(sys.argv[1]).readlines())," myFile

लेकिन इस पोस्ट को अजगर की कमियों के लिए देखें random.shuffle()। यह कई (2080 से अधिक) तत्वों के साथ अच्छी तरह से काम नहीं करेगा।


5

जिम के जवाब से संबंधित:

मेरे ~/.bashrcनिम्नलिखित शामिल हैं:

unsort ()
{
    LC_ALL=C sort -R "$@"
}

जीएनयू कोरुटिल्स के प्रकार के साथ, -R= --random-sort, जो प्रत्येक पंक्ति का एक यादृच्छिक हैश उत्पन्न करता है और इसके द्वारा क्रमबद्ध होता है। रैंडमाइज्ड हैश वास्तव में कुछ पुराने (छोटी गाड़ी) संस्करणों में उपयोग नहीं किया जाएगा, जिससे यह सामान्य सॉर्ट किए गए आउटपुट को वापस कर देगा, यही कारण है कि मैंने सेट किया LC_ALL=C


क्रिस के जवाब से संबंधित:

perl -MList::Util=shuffle -e'print shuffle<>'

एक छोटे से एक लाइनर है। (के -Mmodule=a,b,cलिए आशुलिपि है -e 'use module qw(a b c);')

कारण यह है कि यह एक सरल -iजगह में फेरबदल के लिए काम नहीं करता है क्योंकि पर्ल को उम्मीद है कि printएक ही लूप में फ़ाइल को पढ़ा जा रहा है, और print shuffle <>तब तक आउटपुट नहीं होता है जब तक कि सभी इनपुट फ़ाइलों को पढ़ा और बंद नहीं किया जाता है।

एक छोटे वर्कअराउंड के रूप में,

perl -MList::Util=shuffle -i -ne'BEGIN{undef$/}print shuffle split/^/m'

फ़ाइलों को जगह में फेरबदल करेगा। ( -nइसका अर्थ है "कोड को एक while (<>) {...}लूप में लपेटें ; BEGIN{undef$/}पर्ल लाइनों-ए-टाइम के बजाय फाइलों पर कम से कम समय पर काम करता है, और split/^/mइसकी आवश्यकता है क्योंकि $_=<>लाइनों के बजाय पूरी फाइल के साथ निहित किया गया है।"


उस तरह -R को दोहराते हुए OS X पर मौजूद नहीं है, लेकिन कुछ महान पर्ल उत्तरों के लिए +1, और सामान्य रूप से एक महान जवाब।
क्रिस लुत्ज़

आप OS X पर GNU कोरुटिल स्थापित कर सकते हैं, लेकिन (जैसा कि मैंने अतीत में किया है) आपको सावधान रहना होगा कि बिल्ट-इन टूल्स को न तोड़ें ... कहा जा रहा है, ओपी रेडहैट लिनक्स पर है, जिसमें निश्चित रूप से जीएनयू है coreutils मानक।
१२

3

जब मैं होमब्रे के साथ कोरटिल स्थापित करता हूं

brew install coreutils

shufके रूप में उपलब्ध हो जाता है n


काढ़ा के साथ सभी आदेशों पहले से जुड़ा हुआ gतो shufबन गया gshufमेरे लिए।
Jörn

^ ऐसा इसलिए है क्योंकि वे गैर-पॉसिक्स हैं, या क्या मैं पूरी तरह से बंद हूं?
डेव लिउ

1

डार्विनपोर्ट्स के साथ मैक ओएस एक्स:

sudo port install unsort
cat $file | unsort | ...

1

FreeBSD की अपनी यादृच्छिक उपयोगिता है:

cat $file | random | ...

यह in / usr / games / random है, इसलिए यदि आपने गेम इंस्टॉल नहीं किया है, तो आप भाग्य से बाहर हैं।

आप textproc / rand या textproc / msort जैसे पोर्ट स्थापित करने पर विचार कर सकते हैं। यदि पोर्टेबिलिटी एक चिंता का विषय है, तो ये लिनक्स और / या मैक ओएस एक्स पर उपलब्ध हो सकते हैं।


-1

OSX पर, http://ftp.gnu.org/gnu/coreutils/ से नवीनतम और कुछ पसंद है

./configure मेक सुडो मेक इनस्टॉल

... आपको / usr / स्थानीय / बिन / छाँटना --rrandom- तरह देना चाहिए

बिना मेस / usr / बिन / सॉर्ट के


यह मेरे लिए OSX (10.7) पर काम नहीं किया। मुझे "कॉन्फ़िगर: त्रुटि: सी कंपाइलर निष्पादन योग्य नहीं बना सकता है"।
डोलन एंटेन्यूसी

@dolan अपनी अनुमतियां जांचें?
बेनुबर्ड

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.