উত্তর:
ধরে নিচ্ছি উপাদানগুলি NUL এবং নিউলাইন ছাড়া অন্য অক্ষরের স্ট্রিং রয়েছে (সাবধান হন যে ফাইলের নামগুলিতে নিউলাইনটি বৈধ কিনা), আপনি প্রতি লাইনে একটি উপাদান সহ একটি পাঠ্য ফাইল হিসাবে একটি সেট উপস্থাপন করতে পারেন এবং কিছু মানক ইউনিক্স ইউটিলিটি ব্যবহার করতে পারেন।
$ grep -Fxc 'element' set # outputs 1 if element is in set
# outputs >1 if set is a multi-set
# outputs 0 if element is not in set
$ grep -Fxq 'element' set # returns 0 (true) if element is in set
# returns 1 (false) if element is not in set
$ awk '$0 == "element" { s=1; exit }; END { exit !s }' set
# returns 0 if element is in set, 1 otherwise.
$ awk -v e='element' '$0 == e { s=1; exit } END { exit !s }'
$ comm -12 <(sort set1) <(sort set2) # outputs intersect of set1 and set2
$ grep -xF -f set1 set2
$ sort set1 set2 | uniq -d
$ join -t <(sort A) <(sort B)
$ awk '!done { a[$0]; next }; $0 in a' set1 done=1 set2
$ cmp -s <(sort set1) <(sort set2) # returns 0 if set1 is equal to set2
# returns 1 if set1 != set2
$ cmp -s <(sort -u set1) <(sort -u set2)
# collapses multi-sets into sets and does the same as previous
$ awk '{ if (!($0 in a)) c++; a[$0] }; END{ exit !(c==NR/2) }' set1 set2
# returns 0 if set1 == set2
# returns 1 if set1 != set2
$ awk '{ a[$0] }; END{ exit !(length(a)==NR/2) }' set1 set2
# same as previous, requires >= gnu awk 3.1.5
$ wc -l < set # outputs number of elements in set
$ awk 'END { print NR }' set
$ sed '$=' set
$ comm -23 <(sort -u subset) <(sort -u set) | grep -q '^'
# returns true iff subset is not a subset of set (has elements not in set)
$ awk '!done { a[$0]; next }; { if !($0 in a) exit 1 }' set done=1 subset
# returns 0 if subset is a subset of set
# returns 1 if subset is not a subset of set
$ cat set1 set2 # outputs union of set1 and set2
# assumes they are disjoint
$ awk 1 set1 set2 # ditto
$ cat set1 set2 ... setn # union over n sets
$ sort -u set1 set2 # same, but doesn't assume they are disjoint
$ sort set1 set2 | uniq
$ awk '!a[$0]++' set1 set2 # ditto without sorting
$ comm -23 <(sort set1) <(sort set2)
# outputs elements in set1 that are not in set2
$ grep -vxF -f set2 set1 # ditto
$ sort set2 set2 set1 | uniq -u # ditto
$ awk '!done { a[$0]; next }; !($0 in a)' set2 done=1 set1
$ comm -3 <(sort set1) <(sort set2) | tr -d '\t' # assumes not tab in sets
# outputs elements that are in set1 or in set2 but not both
$ sort set1 set2 | uniq -u
$ cat <(grep -vxF -f set1 set2) <(grep -vxF -f set2 set1)
$ grep -vxF -f set1 set2; grep -vxF -f set2 set1
$ awk '!done { a[$0]; next }; $0 in a { delete a[$0]; next }; 1;
END { for (b in a) print b }' set1 done=1 set2
প্রতি সেট লাইনের জন্য একটি সেট প্রদর্শিত স্থানের সমস্ত সম্ভাব্য সাবসেটগুলি:
$ p() { [ "$#" -eq 0 ] && echo || (shift; p "$@") |
while read r; do printf '%s %s\n%s\n' "$1" "$r" "$r"; done; }
$ p $(cat set)
(ধরে নিলে উপাদানগুলিতে এসপিসি, ট্যাব নেই (এর ডিফল্ট মান ধরে $IFS
)), ব্যাকস্ল্যাশ, ওয়াইল্ডকার্ড অক্ষর রয়েছে।
$ while IFS= read -r a; do while IFS= read -r b; do echo "$a, $b"; done < set1; done < set2
$ awk '!done { a[$0]; next }; { for (i in a) print i, $0 }' set1 done=1 set2
$ comm -12 <(sort set1) <(sort set2) # does not output anything if disjoint
$ awk '++seen[$0] == 2 { exit 1 }' set1 set2 # returns 0 if disjoint
# returns 1 if not
$ wc -l < set # outputs 0 if the set is empty
# outputs >0 if the set is not empty
$ grep -q '^' set # returns true (0 exit status) unless set is empty
$ awk '{ exit 1 }' set # returns true (0 exit status) if set is empty
$ sort set | head -n 1 # outputs the minimum (lexically) element in the set
$ awk 'NR == 1 { min = $0 }; $0 < min { min = $0 }; END { print min }'
# ditto, but does numeric comparison when elements are numerical
$ sort test | tail -n 1 # outputs the maximum element in the set
$ sort -r test | head -n 1
$ awk '$0 > max { max = $0 }; END { print max }'
# ditto, but does numeric comparison when elements are numerical
সমস্ত http://www.catonmat.net/blog/set-operation-in-unix-shell-smplified/ এ উপলব্ধ
sort set1 set2 | uniq -d
মাল্টি-সেটের জন্য কাজ করে না। ব্যবহার বিবেচনা করুন sort <(sort -u set1) <(sort -u set2) | uniq -d
।
প্রকার, রকম. আপনার নিজের বাছাইয়ের সাথে মোকাবিলা comm
করতে হবে , তবে প্রতিটি লাইনকে একটি সেট সদস্য হিসাবে বিবেচনা করে: -12
ছেদ করার -13
জন্য, পার্থক্যের জন্য এটি ব্যবহার করতে পারেন । (এবং -23
আপনাকে set2 - set1
পরিবর্তিত পার্থক্য দেয়, তার পরিবর্তে set1 - set2
)) ইউনিয়ন sort -u
এই সেটআপটিতে রয়েছে।
আমি একটি নির্দিষ্ট সরঞ্জাম জানি না তবে আপনি পাইথন এবং এটির সেট ক্লাস এবং অপারেটরগুলি ব্যবহার করতে পারেন এটি করার জন্য একটি ছোট স্ক্রিপ্ট লিখতে।
উদাহরণের জন্য:
Python> s1 = set(os.listdir("/bin"))
Python> s2 = set(os.listdir("/usr/bin"))
Python> s1 & s2
set(['awk',
'basename',
'chroot', ...
Python> import os
ছোট কনসোল সরঞ্জাম "সেটআপ" এখন 16.10 থেকে দেবিয়ান স্ট্রেচ এবং উবুন্টুতে উপলব্ধ। আপনি এটি মাধ্যমে পেতে পারেন
sudo apt install setop
এখানে কিছু উদাহরণঃ. পরিচালিত হওয়া সেটগুলি বিভিন্ন ইনপুট ফাইল হিসাবে দেওয়া হয়:
setop input # is equal to "sort input --unique"
setop file1 file2 --union # option --union is default and can be omitted
setop file1 file2 file3 --intersection # more than two inputs are allowed
setop file1 - --symmetric-difference # ndash stands for standard input
setop file1 -d file2 # all elements contained in 1 but not 2
বুলিয়ান ক্যোয়ারীগুলি কেবল EXIT_SUCCESS
সত্যের ক্ষেত্রে ফিরে আসে এবং EXIT_FAILURE
পাশাপাশি অন্যথায় কোনও বার্তা দেয়। এইভাবে, সেটআপটি শেলটিতে ব্যবহার করা যেতে পারে।
setop inputfile --contains "value" # is element value contained in input?
setop A.txt B.txt --equal C.txt # union of A and B equal to C?
setop bigfile --subset smallfile # analogous --superset
setop -i file1 file2 --is-empty # intersection of 1 and 2 empty (disjoint)?
ইনপুট স্ট্রিমগুলি কীভাবে পার্স করা হবে তা সঠিকভাবে বর্ণনা করা সম্ভব, আসলে নিয়মিত প্রকাশের মাধ্যমে:
setop input.txt --input-separator "[[:space:]-]"
এর অর্থ হ'ল একটি সাদা \v
\t
\n
\r
\f
স্থান (অর্থাত্ স্পেস) বা বিয়োগ চিহ্নটি উপাদানগুলির মধ্যে বিভাজক হিসাবে ব্যাখ্যা করা হয় (ডিফল্টটি নতুন লাইন, অর্থাত ইনপুট ফাইলের প্রতিটি লাইনই একটি উপাদান)setop input.txt --input-element "[A-Za-z]+"
এর অর্থ হল যে উপাদানগুলি কেবল লাতিন অক্ষর সমন্বিত শব্দ, অন্য সমস্ত অক্ষরকে উপাদানগুলির মধ্যে বিভাজক হিসাবে বিবেচনা করা হয়তদতিরিক্ত, আপনি পারেন
--count
আউটপুট সেট সমস্ত উপাদান,--trim
সমস্ত ইনপুট উপাদান (যেমন স্থান, কমা ইত্যাদি ইত্যাদি সমস্ত অবাঞ্ছিত পূর্ববর্তী এবং পরবর্তী অক্ষরগুলি মুছুন),--include-empty
,--ignore-case
,--output-separator
আউটপুট স্ট্রিমের উপাদানগুলির মধ্যে সেট করুন (ডিফল্ট হয় \n
),আরও তথ্যের জন্য দেখুন man setop
বা github.com/phisigma/setop ।
আপনি যদি কোনও ফাইলকে লাইনের সেট হিসাবে দেখেন এবং ফাইলগুলি বাছাই করা থাকে তবে তা রয়েছে comm
।
আপনি যদি কোনও ফাইলকে (বহু) লাইনের সেট হিসাবে দেখেন এবং লাইনগুলি সাজানো grep
না হয় তবে পার্থক্য এবং ছেদটি করতে পারে (এটি নির্ধারিত পার্থক্য এবং ছেদটি অর্জন করে তবে মাল্টিসেটের জন্য গণনাকে সম্মান করে না)। ইউনিয়ন ঠিক cat
।
grep -xF -f small large >intersection
grep -vxF -f small large >difference
cat small large >union
এটি করার জন্য আমি একটি ছোট সরঞ্জাম লিখেছিলাম যা বিভিন্ন জায়গায় আমার পক্ষে বেশ কার্যকর। ইউআই অপরিশোধিত এবং খুব বড় ফাইলগুলির পারফরম্যান্স বৈশিষ্ট্য সম্পর্কে আমি নিশ্চিত নই (যেহেতু এটি পুরো তালিকাটি মেমরির মধ্যে পড়ে) তবে "এটি আমার পক্ষে কাজ করে"। প্রোগ্রামটি https://github.com/nibrahim/lines এ রয়েছে । এটা পাইথনে আপনি এটি ব্যবহার করে পেতে পারেন pip install lines
।
এটি বর্তমানে ইউনিয়ন, ছেদ, পার্থক্য এবং দুটি ফাইলের প্রতিসম পার্থক্য সমর্থন করে। ইনপুট ফাইলের প্রতিটি লাইন একটি সেট উপাদান হিসাবে বিবেচনা করা হয়।
এটিতে দুটি অতিরিক্ত অপারেশনও রয়েছে। একটি ফাইলের মধ্যে ফাঁকা লাইনগুলি বের করে নিন এবং দ্বিতীয়টি (যা আমার পক্ষে খুব দরকারী) ফাইলটি সন্ধান করা এবং এটি একই স্ট্রিংয়ের সেটে বিভক্ত করা। সাধারণ প্যাটার্নের সাথে মেলে না এমন একটি তালিকায় থাকা ফাইলগুলি অনুসন্ধান করার জন্য আমার এটি দরকার ছিল।
আমি প্রতিক্রিয়া স্বাগত জানাই।
ফাইল সিস্টেমটি ফাইলের নামগুলি (পাথ সহ পুরো ফাইলের নাম) অনন্য হিসাবে বিবেচনা করে।
অপারেশনস?
নতুন, ইউনিয়ন সেট পেতে আপনি খালি ডিরেক্টরি সি / তে ফাইলগুলি একটি এবং এবং বি / তে অনুলিপি করতে পারেন।
ফাইল-পরীক্ষার মতো -e name
এবং লুপগুলি বা সন্ধানের সাহায্যে আপনি দুটি বা ততোধিক ডিরেক্টরিতে থাকা ফাইলগুলি ছেদ করতে বা পার্থক্যটি পরীক্ষা করতে পারেন।
এখানে সেরা উত্তর: সেটডাউন (একটি উত্সর্গীকৃত সরঞ্জাম)
আমি সেটডাউন নামক একটি প্রোগ্রাম লিখেছিলাম যা ক্লায়েন্ট থেকে সেট অপারেশন করে।
এটি মেকফাইলে আপনি যা লিখবেন তার অনুরূপ সংজ্ঞা লিখে সেট অপারেশন সম্পাদন করতে পারে:
someUnion: "file-1.txt" \/ "file-2.txt"
someIntersection: "file-1.txt" /\ "file-2.txt"
someDifference: someUnion - someIntersection
এটি বেশ দুর্দান্ত এবং আপনার এটি পরীক্ষা করা উচিত। আমি ব্যক্তিগতভাবে অ্যাড-হক কমান্ডগুলি ব্যবহার করার পরামর্শ দিচ্ছি না যেগুলি সেট অপারেশনগুলি সম্পাদনের জন্য কাজের জন্য তৈরি করা হয়নি you যখন আপনাকে সত্যিকার অর্থে অনেকগুলি সেট অপারেশন করার দরকার হয় বা যদি আপনার একে অপরের উপর নির্ভর করে এমন কোনও সেট অপারেশন থাকে তবে এটি কার্যকর হবে না t । কেবল এটিই নয় তবে সেটডাউন আপনাকে সেট অপারেশনগুলি লিখতে দেয় যা অন্যান্য সেট অপারেশনগুলির উপর নির্ভর করে!
যে কোনও হারে, আমি মনে করি এটি বেশ দুর্দান্ত এবং আপনার এটি সম্পূর্ণরূপে পরীক্ষা করা উচিত।
সঙ্গে zsh
অ্যারে ( zsh
অ্যারে বাইটের কোনো অবাধ ক্রম, এমনকি 0 ধারণ করতে পারে)।
(এছাড়াও নোট করুন যে এর typeset -U array
গ্যারান্টী দেওয়ার জন্য আপনি এর উপাদানগুলি অনন্য।
if ((${array[(Ie)$element]})); then
echo '$element is in $array'
fi
( I
অ্যারের সাবসিক্রিপ্ট পতাকা ব্যবহার করে অ্যারেতে সর্বশেষ উপস্থিতির সূচক পেতে $element
(বা 0 না পাওয়া গেলে) প্যাটার্ন হিসাবে গ্রহণের জন্য e
( e
এক্স্যাক্টের জন্য) সরান $element
)
if ((n = ${(M)#array:#$element})); then
echo "\$element is found $n times in \$array'
fi
${array:#pattern}
ksh এর উপর একটি পরিবর্তন হচ্ছে ${var#pattern}
যে সরিয়ে ফেলা উপাদান আছে যা প্যাটার্ন হিসাবে শুধু নেতৃস্থানীয় অংশ ধরণের সাথে মেলা মুছে ফেলার জন্য বিরোধিতা মেলে। (M)
(জন্য মিলেছে ) অর্থ reverses এবং সব সরিয়ে ফেলবে কিন্তু মিলেছে উপাদানের (ব্যবহারের $~element
জন্য এটি একটি প্যাটার্ন হিসাবে গ্রহণ করা)।
common=("${(@)set1:*set2}")
${set1:*set2}
অ্যারে ছেদটি করে তবে "${(@)...}"
শূন্য উপাদান সংরক্ষণের জন্য সিনট্যাক্সের প্রয়োজন হয়।
[[ ${(j: :)${(q)array1}} = ${(j: :)${(q)array2}} ]]
অ্যারেগুলি অভিন্ন কিনা (এবং একই ক্রমে) পরীক্ষা করে। q
পরামিতি সম্প্রসারণ পতাকা (মত বিষয়গুলিতে সমস্যা এড়ানোর জন্য উপাদান উদ্ধৃতি a=(1 "2 3")
বনাম b=("1 2" 3)
), এবং (j: :)
একটি স্ট্রিং তুলনা করার আগে স্থান সঙ্গে তাদের যোগদান করে।
তাদের অর্ডার নির্বিশেষে একই উপাদান রয়েছে তা পরীক্ষা করতে o
পতাকাটি অর্ডার করতে ব্যবহার করুন। u
সদৃশগুলি সরানোর জন্য পতাকা (অনন্য )ও দেখুন ।
[[ ${(j: :)${(qo)array1}} = ${(j: :)${(qo)array2}} ]]
n=$#array
if ((${#array1:*array2} == ${#array2})); then
echo '$array2 is included in $array1'
fi
union=("$array1[@]" "$array2[@]")
( ডুপ্লিকেটগুলির ক্ষেত্রে নিতে typeset -U
উপরে বা u
প্যারামিটার সম্প্রসারণের পতাকাটি দেখুন)। আবার যদি খালি স্ট্রিং সম্ভাব্য মানগুলির মধ্যে একটি না হয় তবে আপনি এটিকে সহজ করতে পারবেন:
union=($array1 $array2)
complement=("${(@)array1:|array2}")
এর উপাদানের জন্য $array1
যে হয় না $array2
।
min=${${(o)array}[1]} max=${${(o)array}[-1]}
min=${${(no)array}[1]} max=${${(no)array}[-1]}