আমি এলোমেলোভাবে একটি পাঠ্য ফাইলের লাইনগুলি পরিবর্তন করতে এবং একটি নতুন ফাইল তৈরি করতে চাই। ফাইলটিতে কয়েক হাজার লাইন থাকতে পারে।
আমি কিভাবে যে কি করতে পারেন 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
ইনপুট নেয় না , তবে বিকল্পভাবে যুক্তিগুলির ফাইলও দেয়SIGPIPE
141
। ফাংশন আউটপুটটি পাইপগুলিতে পাইপ করার সময় এটি গুরুত্বপূর্ণ যখন তাড়াতাড়ি বন্ধ হয়ে যায়, যেমন পাইপ করার সময় 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.090s
0.289s
0.589s
1.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.229s
bash
লুপ + 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