আমি এলোমেলোভাবে একটি পাঠ্য ফাইলের লাইনগুলি পরিবর্তন করতে এবং একটি নতুন ফাইল তৈরি করতে চাই। ফাইলটিতে কয়েক হাজার লাইন থাকতে পারে।
আমি কিভাবে যে কি করতে পারেন cat, awk, cut, ইত্যাদি?
আমি এলোমেলোভাবে একটি পাঠ্য ফাইলের লাইনগুলি পরিবর্তন করতে এবং একটি নতুন ফাইল তৈরি করতে চাই। ফাইলটিতে কয়েক হাজার লাইন থাকতে পারে।
আমি কিভাবে যে কি করতে পারেন cat, awk, cut, ইত্যাদি?
উত্তর:
আপনি ব্যবহার করতে পারেন shuf। কিছু সিস্টেমে কমপক্ষে (POSIX তে উপস্থিত হবে না)।
জ্লেদেভ যেমন উল্লেখ করেছেন: sort -Rএটিও একটি বিকল্প হতে পারে। কিছু সিস্টেমে কমপক্ষে; ভাল, আপনি ছবি পেতে। এটি নির্দিষ্ট করে দেওয়া হয়েছে যে sort -Rবদলে যায় না বরং পরিবর্তে আইটেমগুলিকে তাদের হ্যাশ মান অনুসারে বাছাই করে।
[সম্পাদকের দ্রষ্টব্য: ডুপ্লিকেট লাইনগুলি বা সাজানোর কীগুলি সর্বদা একে অপরের পাশে শেষ হয় না দেখে sort -R প্রায় বদলে যায় । অন্য কথায়: কেবল অনন্য ইনপুট লাইন / কীগুলির সাথে এটিই একটি সত্য পরিবর্তন। যদিও এটি সত্য যে আউটপুট ক্রম হ্যাশ মান দ্বারা নির্ধারিত হয় , এলোমেলোভাবে একটি র্যান্ডম হ্যাশ ফাংশন চয়ন করে আসে - ম্যানুয়াল দেখুন ]]
shufএবং sort -Rকিছুটা পার্থক্য করুন, কারণ sort -Rএলোমেলোভাবে হ্যাশ অনুযায়ী উপাদানগুলিকে এলোমেলোভাবে আদেশ করে, যা sort -Rপুনরাবৃত্ত উপাদানগুলিকে একসাথে রাখবে, এবং shufসমস্ত উপাদান এলোমেলোভাবে পরিবর্তিত করে।
brew install coreutilsতারপরে gshuf ...(:
sort -Rএবং shufসম্পূর্ণ আলাদা হিসাবে দেখা উচিত। sort -Rনির্বিচারবাদী। আপনি যদি একই ইনপুটটিতে বিভিন্ন সময়ে দু'বার কল করেন তবে একই উত্তর পাবেন। shufঅন্যদিকে, এলোমেলো আউটপুট উত্পাদন করে, তাই সম্ভবত এটি একই ইনপুটটিতে বিভিন্ন আউটপুট দেয়।
পার্ল ওয়ান-লাইনারটি ম্যাক্সিমের সমাধানের সহজ সংস্করণ হবে
perl -MList::Util=shuffle -e 'print shuffle(<STDIN>);' < myfile
\n; হ্যাঁ, যে \nউপস্থিত থাকা আবশ্যক - এবং এটি সাধারণত হয় - অন্যথায় তুমি যা বর্ণনা পাবেন।
<STDIN>সঙ্গে <>, তাই সমাধান থেকে ইনপুট সঙ্গে কাজ করে ফাইল খুব।
এই উত্তরটি নিম্নলিখিত উপায়ে প্রচুর দুর্দান্ত উত্তরগুলি পরিপূরক করে:
বিদ্যমান উত্তরগুলি নমনীয় শেল ফাংশনগুলিতে প্যাকেজ করা হয় :
stdinইনপুট নেয় না , তবে বিকল্পভাবে যুক্তিগুলির ফাইলও দেয়SIGPIPE141 । ফাংশন আউটপুটটি পাইপগুলিতে পাইপ করার সময় এটি গুরুত্বপূর্ণ যখন তাড়াতাড়ি বন্ধ হয়ে যায়, যেমন পাইপ করার সময় head।একটি পারফরম্যান্স তুলনা করা হয়।
awk, sortএবংcut , থেকে অভিযোজিত ওপি নিজস্ব উত্তর :shuf() { awk 'BEGIN {srand(); OFMT="%.17f"} {print rand(), $0}' "$@" |
sort -k1,1n | cut -d ' ' -f2-; }
shuf() { perl -MList::Util=shuffle -e 'print shuffle(<>);' "$@"; }
shuf() { python -c '
import sys, random, fileinput; from signal import signal, SIGPIPE, SIG_DFL;
signal(SIGPIPE, SIG_DFL); lines=[line for line in fileinput.input()];
random.shuffle(lines); sys.stdout.write("".join(lines))
' "$@"; }
এই ফাংশনটির একটি উইন্ডোজ সংস্করণের নীচের অংশটি দেখুন ।
shuf() { ruby -e 'Signal.trap("SIGPIPE", "SYSTEM_DEFAULT");
puts ARGF.readlines.shuffle' "$@"; }
পারফরম্যান্স তুলনা:
দ্রষ্টব্য: এই সংখ্যাগুলি ওএসএক্স 10.10.3 চলমান 3.2 গিগাহার্টজ ইন্টেল কোর আই 5 এবং একটি ফিউশন ড্রাইভের সাথে 2012 সালের শেষের দিকে আইম্যাকে প্রাপ্ত হয়েছিল। ওএস ব্যবহৃত, মেশিন স্পেস, awkপ্রয়োগ বাস্তবায়নের সাথে সময় পরিবর্তিত হয় (উদাহরণস্বরূপ, awkওএসএক্সে ব্যবহৃত বিএসডি সংস্করণটি সাধারণত জিএনইউর তুলনায় ধীর হয় awkএবং বিশেষত mawk), এটি আপেক্ষিক পারফরম্যান্সের একটি সাধারণ ধারণা প্রদান করে ।
ইনপুট ফাইলটি 1 মিলিয়ন-লাইনের ফাইল সহ উত্পাদিত হয় seq -f 'line %.0f' 1000000।
টাইমস আরোহী ক্রমে তালিকাভুক্ত করা হয়েছে (দ্রুততম প্রথম):
shuf
0.090s0.289s0.589s1.342sপাইথন ২.7..6 সহ; 2.407s(!) পাইথন সহ 3.4.2awk+ sort+cut
3.003sবিএসডি সহ awk; 2.388sজিএনইউ awk(4.1.1) সহ; 1.811sসঙ্গে mawk(1.3.4);আরও তুলনার জন্য, সমাধানগুলি উপরে ফাংশন হিসাবে প্যাকেজ করা হয়নি:
sort -R (ডুপ্লিকেট ইনপুট লাইন থাকলে সত্যিকারের রদবদল নয়)
10.661s - বেশি মেমরি বরাদ্দ করা কোনও পার্থক্য বলে মনে হচ্ছে না24.229sbash লুপ + sort
32.593sউপসংহার :
shufআপনি যদি পারেন তবে ব্যবহার করুন - এটি এখন পর্যন্ত দ্রুততম।awk+ sort+ cutকম্বো ব্যবহার করুন ; আপনি যে awkপ্রয়োগগুলি বিষয়গুলি ব্যবহার করেন ( mawkজিএনইউর চেয়ে দ্রুত awk, বিএসডি awkসবচেয়ে ধীর)।sort -R, bashলুপ, এবং Scala।পাইথন সলিউশনের উইন্ডোজ সংস্করণগুলি (উইন্ডোতে সমর্থিত নয় এমন সিগন্যাল সম্পর্কিত বিবৃতিগুলি উদ্ধৃতকরণের পরিবর্তনের জন্য এবং পাইথন কোডটি অভিন্ন):
$OutputEncodingযদি পাইপলাইনের মাধ্যমে নন-এএসসিআইআই অক্ষরগুলি প্রেরণ করতে চান তবে আপনাকে সামঞ্জস্য করতে হবে ):# Call as `shuf someFile.txt` or `Get-Content someFile.txt | shuf`
function shuf {
$Input | python -c @'
import sys, random, fileinput;
lines=[line for line in fileinput.input()];
random.shuffle(lines); sys.stdout.write(''.join(lines))
'@ $args
}
নোট করুন যে পাওয়ারশেল স্থানীয়ভাবে এটির Get-Randomসেমিডলেট মাধ্যমে পরিবর্তন করতে পারে (যদিও পারফরম্যান্সে সমস্যা হতে পারে); উদাহরণ:
Get-Content someFile.txt | Get-Random -Count ([int]::MaxValue)
cmd.exe(ক ব্যাচ ফাইল):ফাইল হিসাবে সংরক্ষণ করুন shuf.cmd:
@echo off
python -c "import sys, random, fileinput; lines=[line for line in fileinput.input()]; random.shuffle(lines); sys.stdout.write(''.join(lines))" %*
python -c "import sys, random; lines = [x for x in sys.stdin.read().splitlines()] ; random.shuffle(lines); print(\"\n\".join([line for line in lines]));"
from signal import signal, SIGPIPE, SIG_DFL; signal(SIGPIPE, SIG_DFL);আসল সমাধান থেকে বাদ দেওয়া যথেষ্ট, এবং ফাইল নাম যুক্তিগুলিও পাস করতে পারার নমনীয়তা ধরে রাখে - অন্য কোনও পরিবর্তন করার দরকার নেই (উদ্ধৃতি ব্যতীত) - দয়া করে আমি নতুন বিভাগটি যুক্ত করেছি দেখুন নীচে।
আমি একটি ক্ষুদ্র পার্ল স্ক্রিপ্ট ব্যবহার করি, যাকে আমি "আনসোর্ট" বলি:
#!/usr/bin/perl
use List::Util 'shuffle';
@list = <STDIN>;
print shuffle(@list);
আমি একটি নূল-সীমাবদ্ধ সংস্করণও পেয়েছি, যার নাম "আনসোর্ট 0" ... ফাইন্ড-প্রিন্ট0 এবং আরও কিছু ব্যবহারের জন্য সহজ।
পিএস: 'শুফ' কেও ভোট দিয়েছেন, আমার কোনও ধারণা ছিল না যে আজকাল কোর্টিলগুলিতে ছিল ... আপনার সিস্টেমে 'শুফ' না থাকলে উপরেরটি এখনও কার্যকর হতে পারে।
<STDIN>সঙ্গে <>অর্ডার থেকে ইনপুট সঙ্গে সমাধান কাজ করার জন্য ফাইল খুব।
এখানে প্রথম চেষ্টা যা কোডারটিতে সহজ তবে সিপিইউতে কঠোর যা প্রতিটি লাইনে একটি এলোমেলো সংখ্যাকে প্রিন্ড করে, সেগুলি সাজায় এবং তারপরে প্রতিটি লাইন থেকে এলোমেলো সংখ্যাটি সরিয়ে দেয়। বাস্তবে, লাইনগুলি এলোমেলোভাবে বাছাই করা হয়:
cat myfile | awk 'BEGIN{srand();}{print rand()"\t"$0}' | sort -k1 -n | cut -f2- > myfile.shuffled
head myfile | awk ...। তারপরে আমি এটিকে কেবল বিড়ালতে পরিবর্তন করি; এই কারণেই এটি সেখানে রেখে দেওয়া হয়েছিল।
-k1 -nবাছাইয়ের দরকার নেই , যেহেতু awk এর আউটপুট rand()0 এবং 1 এর মধ্যে দশমিক এবং কারণ যে সমস্ত বিষয় এটি একরকম পুনঃক্রম হয়। -k1বাকী রেখাকে উপেক্ষা করে এটিকে গতিতে সহায়তা করতে পারে যদিও র্যান্ড () এর আউটপুট তুলনা শর্ট সার্কিটের পক্ষে যথেষ্ট অনন্য হওয়া উচিত।
cat filename |(বা < filename |) রাখা ভাল ।
এখানে একটি awk স্ক্রিপ্ট আছে
awk 'BEGIN{srand() }
{ lines[++d]=$0 }
END{
while (1){
if (e==d) {break}
RANDOM = int(1 + rand() * d)
if ( RANDOM in lines ){
print lines[RANDOM]
delete lines[RANDOM]
++e
}
}
}' file
আউটপুট
$ cat file
1
2
3
4
5
6
7
8
9
10
$ ./shell.sh
7
5
10
9
6
8
2
1
3
4
awkসঙ্গে sortএবং cut। কয়েক হাজার লাইনের বেশি না হওয়ার জন্য এটি খুব বেশি পার্থক্য রাখে না, তবে উচ্চতর লাইনের গণনার সাথে এটি গুরুত্বপূর্ণ (প্রান্তিক ব্যবহারটি awkবাস্তবায়নের উপর নির্ভর করে )। কিছুটা সরলকরণ হ'ল লাইনগুলি while (1){এবং এর if (e==d) {break}সাথে প্রতিস্থাপন করা while (e<d)।
পাইথনের জন্য একটি ওয়ান-লাইনার:
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()। এটি অনেকগুলি (২০০০ এর বেশি) উপাদানগুলির সাথে ভালভাবে কাজ করবে না।
/dev/urandom। পাইথন থেকে এটা ব্যবহার করতে: random.SystemRandom().shuffle(L)।
.readLines()লাইনের সাথে লাইনগুলি ফিরিয়ে দেয় ।
সাধারণ অ্যাজক-ভিত্তিক ফাংশনটি কাজটি করবে:
shuffle() {
awk 'BEGIN{srand();} {printf "%06d %s\n", rand()*1000000, $0;}' | sort -n | cut -c8-
}
ব্যবহার:
any_command | shuffle
এটি প্রায় যে কোনও ইউএনআইএক্স-এ কাজ করা উচিত। লিনাক্স, সোলারিস এবং এইচপি-ইউএক্স পরীক্ষিত।
হালনাগাদ:
দ্রষ্টব্য, যে নেতৃস্থানীয় শূন্যগুলি ( %06d) এবং rand()গুণটি এটি sortসংখ্যাগুলিতে বোঝে না এমন সিস্টেমেও সঠিকভাবে কাজ করতে সক্ষম করে । এটি অভিধানিক ক্রমের মাধ্যমে বাছাই করা যেতে পারে (ওরফে সাধারণ স্ট্রিং তুলনা)।
"$@"এটি ফাইলগুলির সাথে ইনপুট হিসাবেও কাজ করবে । গুণনের কোনও কারণ নেই rand(), কারণ sort -nদশমিক ভগ্নাংশগুলি বাছাই করতে সক্ষম। এটা নিয়ন্ত্রণ করে নেওয়া ভালো তবে হয়, awkকারণ ডিফল্ট বিন্যাস সঙ্গে এর আউটপুট ফরম্যাট, %.6g, rand()ইচ্ছা আউটপুটে অনিয়মিত সংখ্যা সূচকীয় স্বরলিপি। যদিও 1 মিলিয়ন লাইন অবধি পরিবর্তিত হওয়া অনুশীলনে যথেষ্ট ততটুকু, পারফরম্যান্সের বেশিরভাগ শুল্ক না দিয়ে আরও লাইন সমর্থন করা সহজ; যেমন %.17f।
sortদশমিক ভগ্নাংশ পরিচালনা করতে সক্ষম হওয়া উচিত (হাজার হাজার বিভাজক সহ, আমি যেমন লক্ষ্য করেছি)।
রুবি এফটিডব্লিউ:
ls | ruby -e 'puts STDIN.readlines.shuffle'
puts ARGF.readlines.shuffleএটিকে উভয় স্টিডিন ইনপুট এবং ফাইল নাম যুক্তি দিয়ে কাজ করতে পারেন।
ruby -e 'puts $<.sort_by{rand}'- এআরজিএফ ইতিমধ্যে একটি গণনাযোগ্য, তাই আমরা এলোমেলো মান অনুসারে বাছাই করে লাইনগুলিকে পরিবর্তন করতে পারি।
স্কাইয়ের উত্তরের ভিত্তিতে পাইথনের জন্য একটি লাইনার , তবে ক) স্টিডিন নেয়, খ) বীজের সাথে ফলাফলটি পুনরাবৃত্তিযোগ্য করে তোলে, গ) সমস্ত লাইনগুলির মধ্যে মাত্র 200 টি বের করে।
$ cat file | python -c "import random, sys;
random.seed(100); print ''.join(random.sample(sys.stdin.readlines(), 200))," \
> 200lines.txt
একটি সহজ এবং স্বজ্ঞাত উপায় ব্যবহার করা হবে shuf।
উদাহরণ:
words.txtহিসাবে অনুমান :
the
an
linux
ubuntu
life
good
breeze
লাইন পরিবর্তন করতে, করুন:
$ shuf words.txt
যা পরিবর্তিত রেখাগুলিকে স্ট্যান্ডার্ড আউটপুটে ফেলে দেয় ; সুতরাং, আপনি এটিকে একটি আউটপুট ফাইলের মতো পাইপ করতে হবে :
$ shuf words.txt > shuffled_words.txt
এই জাতীয় একটি পরিবর্তন চালাতে পারে:
breeze
the
linux
an
ubuntu
good
life
এটি একটি পাইথন স্ক্রিপ্ট যা আমি আমার হোম ফোল্ডারে র্যান্ড.পি হিসাবে সংরক্ষণ করেছি:
#!/bin/python
import sys
import random
if __name__ == '__main__':
with open(sys.argv[1], 'r') as f:
flist = f.readlines()
random.shuffle(flist)
for line in flist:
print line.strip()
ম্যাক ওএসএক্স-এ sort -Rএবং shufউপলভ্য নয় যাতে আপনি এটি আপনার বাশ_প্রফাইলে এইরূপ করতে পারেন:
alias shuf='python rand.py'
আমার মতো যদি আপনি এখানে shufম্যাকোসের বিকল্পের সন্ধান করতে এসেছিলেন তবে ব্যবহার করুন randomize-lines।
ইনস্টল করুন randomize-lines(হোমব্রিউ) প্যাকেজ, যার একটি rlকমান্ড রয়েছে যার সাথে একই কার্যকারিতা রয়েছে shuf।
brew install randomize-lines
Usage: rl [OPTION]... [FILE]...
Randomize the lines of a file (or stdin).
-c, --count=N select N lines from the file
-r, --reselect lines may be selected multiple times
-o, --output=FILE
send output to file
-d, --delimiter=DELIM
specify line delimiter (one character)
-0, --null set line delimiter to null character
(useful with find -print0)
-n, --line-number
print line number with output lines
-q, --quiet, --silent
do not output any errors or warnings
-h, --help display this help and exit
-V, --version output version information and exit
brew install coreutilsপ্রদান করে shufযেমন বাইনারি gshuf।
যদি আপনি স্কেলা ইনস্টল করেন তবে ইনপুটটি সাফ করতে এখানে একটি ওয়ান-লাইনার রয়েছে:
ls -1 | scala -e 'for (l <- util.Random.shuffle(io.Source.stdin.getLines.toList)) println(l)'
এই ব্যাশ ফাংশনটির সর্বনিম্ন নির্ভরতা রয়েছে (কেবলমাত্র বাছাই করুন এবং বাশ করুন):
shuf() {
while read -r x;do
echo $RANDOM$'\x1f'$x
done | sort |
while IFS=$'\x1f' read -r x y;do
echo $y
done
}
awkঅনুমোদিত সমাধানের সাথে সমান্তরাল হয় , তবে কার্যকারিতা বৃহত্তর ইনপুট নিয়ে সমস্যা হবে; আপনার একক $RANDOMমানের ব্যবহারটি কেবল 32,768 ইনপুট লাইন পর্যন্ত সঠিকভাবে বদলে যায়; আপনি যখন এই ব্যাপ্তিটি প্রসারিত করতে পারেন, সম্ভবত এটি উপযুক্ত নয়: উদাহরণস্বরূপ, আমার মেশিনে, আপনার স্ক্রিপ্টটি 32,768 সংক্ষিপ্ত ইনপুট লাইনে চালাতে প্রায় 1 সেকেন্ড সময় লাগে, যা দৌড়তে প্রায় 150 গুণ shufসময় এবং 10-15 বারের মতো লাগে যতক্ষণ না ওপি-র নিজস্ব- awkঅনুমোদিত সমাধান লাগে solution আপনি যদি sortউপস্থিত থাকার উপর নির্ভর করতে পারেন awkতবে পাশাপাশি থাকা উচিত।
উইন্ডোতে আপনি আপনার ব্যাচ ফাইলটি আপনার ডেটা বদল করতে সহায়তা করতে পারেন xt টেক্সট, ব্যাচ কোডের ব্যবহারটি হ'ল
C:\> type list.txt | shuffle.bat > maclist_temp.txt
এই কমান্ডটি জারি করার পরে, maclist_temp.txt এ লাইনের একটি এলোমেলো তালিকা থাকবে।
আশাকরি এটা সাহায্য করবে.
এখনও হিসাবে উল্লেখ করা হয়নি:
ব্যবহার unsort। সিনট্যাক্স (কিছুটা প্লেলিস্ট ওরিয়েন্টেড):
unsort [-hvrpncmMsz0l] [--help] [--version] [--random] [--heuristic]
[--identity] [--filenames[=profile]] [--separator sep] [--concatenate]
[--merge] [--merge-random] [--seed integer] [--zero-terminated] [--null]
[--linefeed] [file ...]msort লাইন দ্বারা পরিবর্তন করতে পারে, তবে এটি সাধারণত ওভারকিল:
seq 10 | msort -jq -b -l -n 1 -c r