ইউনিক্স কমান্ড লাইনের কোনও ফাইল থেকে এলোমেলো লাইন পড়ার সহজ উপায় কী?
ইউনিক্স কমান্ড লাইনের কোনও ফাইল থেকে এলোমেলো লাইন পড়ার সহজ উপায় কী?
উত্তর:
আপনি ব্যবহার করতে পারেন shuf:
shuf -n 1 $FILE
একটি ইউটিলিটিও বলা হয় rl। ডেবিয়ান এ এটি randomize-linesপ্যাকেজে রয়েছে যা আপনি যা চান ঠিক তেমন করে, যদিও সমস্ত ডিস্ট্রোজে পাওয়া যায় না। এর হোম পৃষ্ঠায় এটি shufপরিবর্তে ব্যবহারের প্রস্তাব দেয় (এটি তৈরি করার সময় উপস্থিত ছিল না, আমি বিশ্বাস করি)। shufজিএনইউ কোর্টিলস এর অংশ, rlনা।
rl -c 1 $FILE
shufটিপ দেওয়ার জন্য ধন্যবাদ , এটি ফেডোরায় অন্তর্নির্মিত।
sort -Rস্পষ্টভাবে এক অপেক্ষা করতে যাচ্ছে অনেক 80kk লাইন - -, যেহেতু, যদি যথেষ্ট বিশাল ফাইল সঙ্গে তার আচরণ shuf -nকাজ করে বেশ তাত্ক্ষণিকভাবে।
coreutilsহোমব্রিউ থেকে ইনস্টল করে ওএস এক্স-এ শিফ পেতে পারেন । gshufপরিবর্তে ডাকা হতে পারে shuf।
randomize-linesওএস এক্স এর মাধ্যমে ব্যবহার করতে পারেনbrew install randomize-lines; rl -c 1 $FILE
shufএটি জিএনইউ কোরিউটিলের অংশ এবং সুতরাং অগত্যা * বিএসডি সিস্টেমে (বা ম্যাক?) উপলব্ধ হবে না (ডিফল্টরূপে)। নীচে @ ট্র্যাকার 1 এর পার্ল ওয়ান-লাইনারটি আরও বহনযোগ্য (এবং আমার পরীক্ষাগুলি দ্বারা, কিছুটা দ্রুত)।
অন্য বিকল্প:
head -$((${RANDOM} % `wc -l < file` + 1)) file | tail -1
(${RANDOM} << 15) + ${RANDOM}। এটি লক্ষণীয়ভাবে হ্রাস করে এবং এটি 1 বিলিয়ন লাইন থাকা ফাইলগুলির জন্য কাজ করতে দেয়।
+এবং |একই যেহেতু ${RANDOM}0..32767 সংজ্ঞা দ্বারা হয়।
sort --random-sort $FILE | head -n 1
(আমি উপরে শূফ পদ্ধতির তুলনায় আরও ভাল পছন্দ করি - এমনকি আমি জানতাম না যে এর অস্তিত্ব আছে এবং আমি নিজেই সেই সরঞ্জামটি পাইনি)
sortআমার কোনও সিস্টেমে কাজ করেনি (সেন্টস 5.5, ম্যাক ওএস 10.7.2)। এছাড়াও, বিড়ালের অকেজো ব্যবহার, এটিকে হ্রাস করা যেতে পারেsort --random-sort < $FILE | head -n 1
sort -R <<< $'1\n1\n2' | head -11 এবং 2 ফেরত আসার সম্ভাবনা রয়েছে কারণ sort -Rডুপ্লিকেট লাইন একসাথে সাজানো হয়েছে। এটি একই ক্ষেত্রে প্রযোজ্য sort -Ruকারণ এটি সদৃশ লাইনগুলি সরিয়ে দেয়।
sortপাইপ দেওয়ার আগে পুরো ফাইলটি বদলানো দরকার head। shufপরিবর্তে ফাইল থেকে এলোমেলো লাইনগুলি নির্বাচন করে এবং এটি আমার জন্য আরও দ্রুত।
sort --random-sort $FILE | headসবচেয়ে ভাল হবে, কারণ এটি সরাসরি ফাইলটি অ্যাক্সেস করার অনুমতি দেয়, সম্ভবত দক্ষ সমান্তরাল বাছাই সক্ষম করে
--random-sortএবং -Rঅপশন গনুহ সাজানোর নির্দিষ্ট হয় (তাই তারা বাসদ বা ম্যাক অপারেটিং সিস্টেম সাথে কাজ করবে না sort)। জিএনইউ বাছাই 2005 সালে এই পতাকাগুলি শিখেছে যাতে আপনার জিএনইউ কোর্টিলগুলি 6.0 বা আরও নতুন (যেমন সেন্টস 6) দরকার।
এটি সহজ।
cat file.txt | shuf -n 1
মঞ্জুর যে এটি "shuf -n 1 file.txt" এর থেকে নিজের চেয়ে ধীরে ধীরে কম ad
-n 11 লাইন নির্দিষ্ট করে এবং আপনি এটি 1 টিরও বেশিতে পরিবর্তন করতে পারেন shufঅন্যান্য জিনিসের জন্যও ব্যবহার করা যেতে পারে; আমি কেবল পাইপ দিয়েছিলাম ps auxএবং এর grepসাথে এলোমেলোভাবে কোনও নামের সাথে মিলে যাওয়া প্রক্রিয়াগুলিকে এলোমেলোভাবে হত্যা করি।
perlfaq5: আমি কোনও ফাইল থেকে এলোমেলো লাইনটি কীভাবে নির্বাচন করব? উট বইয়ের একটি জলাধার-নমুনা সংক্রান্ত অ্যালগরিদম এখানে:
perl -e 'srand; rand($.) < 1 && ($line = $_) while <>; print $line;' file
পুরো ফাইলটি পড়ার ক্ষেত্রে স্পেসে এটির একটি উল্লেখযোগ্য সুবিধা রয়েছে Donald আপনি ডোনাল্ড ই নুথের আর্ট অফ কম্পিউটার প্রোগ্রামিং, খণ্ড 2, বিভাগ 3.4.2-এ এই পদ্ধতির একটি প্রমাণ পেতে পারেন।
shuf। পার্ল কোডটি খুব সামান্য দ্রুত (ব্যবহারকারী সময় অনুসারে 8% দ্রুত, সিস্টেম সময় দ্বারা 24% দ্রুত) যদিও উপাহ্যভাবে আমি পার্ল কোডটি "মনে হয়" কম এলোমেলোভাবে পেয়েছি (আমি এটি ব্যবহার করে একটি জুকবক্স লিখেছি)।
shufসম্পূর্ণ ইনপুট ফাইলটিকে মেমরিতে সঞ্চয় করে , যা একটি ভয়ঙ্কর ধারণা, যখন এই কোডটি কেবল একটি লাইন সঞ্চয় করে, তাই এই কোডটির সীমা INNMAMA এর একটি লাইন গণনা (2 ^ 31 বা 2 ^ 63 আপনার উপর নির্ভর করে) খিলান), এর নির্বাচিত সম্ভাব্য লাইনগুলির কোনও স্মরণে ফিট করে।
একটি বাশ স্ক্রিপ্ট ব্যবহার:
#!/bin/bash
# replace with file to read
FILE=tmp.txt
# count number of lines
NUM=$(wc - l < ${FILE})
# generate random number in range 0-NUM
let X=${RANDOM} % ${NUM} + 1
# extract X-th line
sed -n ${X}p ${FILE}
একক বাশ লাইন:
sed -n $((1+$RANDOM%`wc -l test.txt | cut -f 1 -d ' '`))p test.txt
সামান্য সমস্যা: নকল ফাইলের নাম।
wc -l < test.txtযাও পাইপ থাকার এড়ানো cut।
এখানে একটি সাধারণ পাইথন স্ক্রিপ্ট যা কাজটি করবে:
import random, sys
lines = open(sys.argv[1]).readlines()
print(lines[random.randrange(len(lines))])
ব্যবহার:
python randline.py file_to_get_random_line_from
import random, sys lines = open(sys.argv[1]).readlines() আমি সীমার মধ্যে (লেন (লাইন)): র্যান্ড = এলোমেলো.রেন্ডিন্ট (0, লেন (লাইন) -1) মুদ্রণ লাইন.পপ (র্যান্ড),
len(lines)সূচিপত্রের দিকে নিয়ে যেতে পারে। আপনি ব্যবহার করতে পারে print(random.choice(list(open(sys.argv[1]))))। স্মৃতিশক্তি দক্ষ জলাধার স্যাম্পলিং অ্যালগরিদম এছাড়াও আছে ।
' Awk ' ব্যবহারের অন্য উপায়
awk NR==$((${RANDOM} % `wc -l < file.name` + 1)) file.name
$RANDOMএটি একটি বাশিজম )। উপরে @ ট্র্যাকার 1 এর উদ্ধৃত পারফ্যালাক 5 কোডের মতো একই যুক্তি ব্যবহার করে একটি খাঁটি অজগর (মওক) পদ্ধতি রয়েছে: awk 'rand() * NR < 1 { line = $0 } END { print line }' file.name(বাহ, এটি পার্ল কোডের চেয়েও খাটো !)
wcলাইন গণনা পেতে সেই কোডটি অবশ্যই ফাইল ( ) পড়তে হবে, তারপরে awkপ্রদত্ত এলোমেলো লাইন নম্বরটির সামগ্রী পেতে ফাইলটি আবার (অংশ) পড়তে হবে । I / O এলোমেলো নম্বর পাওয়ার চেয়ে অনেক বেশি ব্যয়বহুল হবে। আমার কোডটি কেবল একবার ফাইলটি পড়ে। অ্যাজকের সমস্যাটি rand()হ'ল এটি সেকেন্ডের উপর ভিত্তি করে বীজ বজায় রাখে , তাই আপনি যদি এটিকে টানা খুব দ্রুত চালনা করেন তবে নকল পাবেন।
এমন একটি সমাধান যা ম্যাকোএসএক্স-এও কাজ করে এবং লিনাক্স (?) এও কাজ করে:
N=5
awk 'NR==FNR {lineN[$1]; next}(FNR in lineN)' <(jot -r $N 1 $(wc -l < $file)) $file
কোথায়:
N আপনি চান এলোমেলো রেখার সংখ্যা
NR==FNR {lineN[$1]; next}(FNR in lineN) file1 file2
-> লিখিত নম্বরগুলি সংরক্ষণ করুন file1এবং তারপরে সংশ্লিষ্ট লাইনটি প্রিন্ট করুনfile2
jot -r $N 1 $(wc -l < $file)-> এর সাথে পরিসীমা Nএলোমেলোভাবে সংখ্যা আঁকুন । প্রক্রিয়া প্রতিস্থাপন এটি দোভাষীর ফাইলের মতো দেখায়, সুতরাং আগের উদাহরণে।-r(1, number_of_line_in_file)jot<()file1#!/bin/bash
IFS=$'\n' wordsArray=($(<$1))
numWords=${#wordsArray[@]}
sizeOfNumWords=${#numWords}
while [ True ]
do
for ((i=0; i<$sizeOfNumWords; i++))
do
let ranNumArray[$i]=$(( ( $RANDOM % 10 ) + 1 ))-1
ranNumStr="$ranNumStr${ranNumArray[$i]}"
done
if [ $ranNumStr -le $numWords ]
then
break
fi
ranNumStr=""
done
noLeadZeroStr=$((10#$ranNumStr))
echo ${wordsArray[$noLeadZeroStr]}
আমার ম্যাক ওএস সমস্ত সহজ উত্তর ব্যবহার করে না বলে আমি এখানে আবিষ্কার করেছি। আমি জট কমান্ডটি একটি সংখ্যা তৈরি করতে ব্যবহার করেছি যেহেতু $ RANDOM পরিবর্তনশীল সমাধানগুলি আমার পরীক্ষায় খুব এলোমেলো মনে হচ্ছে না। আমার সমাধানটি পরীক্ষা করার সময় আমার আউটপুট সরবরাহকৃত সমাধানগুলির মধ্যে বিস্তৃত পরিবর্তন ছিল।
RANDOM1=`jot -r 1 1 235886`
#range of jot ( 1 235886 ) found from earlier wc -w /usr/share/dict/web2
echo $RANDOM1
head -n $RANDOM1 /usr/share/dict/web2 | tail -n 1
ভেরিয়েবলের প্রতিধ্বনি হ'ল উত্পাদিত এলোমেলো সংখ্যার ভিজ্যুয়াল পাওয়া।
কেবল ভ্যানিলা সেড এবং অ্যাজক ব্যবহার করা এবং ILE র্যান্ডোম ব্যবহার না করেই একটি সরল, স্পেস-দক্ষ এবং যুক্তিসঙ্গতভাবে দ্রুত "ওয়ান-লাইনার" ফাইলের নাম হিসাবে ফাইল ফাইল থেকে সিউডো-এলোমেলোভাবে নির্বাচন করার জন্য নিম্নরূপ:
sed -n $(awk 'END {srand(); r=rand()*NR; if (r<NR) {sub(/\..*/,"",r); r++;}; print r}' FILENAME)p FILENAME
(এটি FILENAME খালি থাকা সত্ত্বেও কাজ করে, এক্ষেত্রে কোনও লাইন নির্গত হয় না))
এই পদ্ধতির সম্ভাব্য সুবিধা হ'ল এটি একবারে কেবল র্যান্ড () কল করে।
মন্তব্যগুলিতে @ অ্যাডাম ক্যাটজ দ্বারা চিহ্নিত হিসাবে, আরও একটি সম্ভাবনা প্রতিটি লাইনের জন্য র্যান্ড () কল করা হবে:
awk 'rand() * NR < 1 { line = $0 } END { print line }' FILENAME
(অন্তর্ভুক্তির ভিত্তিতে নির্ভুলতার একটি সহজ প্রমাণ দেওয়া যেতে পারে))
rand()"গাওক সহ বেশিরভাগ বিশৃঙ্খলা বাস্তবায়নে, র্যান্ড () প্রতিটি বার যখন আপনি খালি চালায় তখন একই প্রারম্ভিক নম্বর বা বীজ থেকে সংখ্যা উত্পন্ন করতে শুরু করে।"
- https://www.gnu.org/software/gawk/manual/html_node/Numeric-Funifications.html