লিনাক্স সরঞ্জামগুলি ফাইলগুলি সেট হিসাবে বিবেচনা করে এবং সেগুলিতে সেট অপারেশন করে


81

ফাইলগুলি সেট হিসাবে গণ্য করার জন্য এবং সেগুলির উপর সেট অপারেশন করার জন্য বিশেষভাবে ডিজাইন করা কোনও লিনাক্স সরঞ্জাম সম্পর্কে কেউ কি জানেন? পার্থক্য, ছেদ ইত্যাদি পছন্দ?

উত্তর:


110

ধরে নিচ্ছি উপাদানগুলি 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/ এ উপলব্ধ


1
আমি মনে করি পাইথন সংস্করণটি অনেক সহজ এবং স্বজ্ঞাত। ;-)
কীথ

আমি মনে করি এটি সবচেয়ে সম্পূর্ণ উত্তর। দুর্ভাগ্যক্রমে কোনটি চালানোর আদেশ দেয় বা প্রতিটি ক্ষেত্রে কোন যুক্তি (কম -12, -23, -13) সর্বদা "ছেদ" বা "পার্থক্য" হিসাবে স্বজ্ঞাত নয়। তাদের চারপাশে একটি মোড়ক তৈরি করতে পারে, যেহেতু আমি সবসময় এই জিনিসগুলি ব্যবহার করি।
নীল্টন

আমি [পোল @ লোকালহোস্ট ইনস্টিটিউট] দৌড়েছি $ গ্রেপ-এক্সসি এবং ইনস্টল-বাইনারি 0 [পোল @ লোকালহোস্ট ইনস্টিটিউট] $ তবে আমি এর অর্থ কী তা বুঝতে পারি না। "এবং" শব্দটি ফাইলটিতে বহুবার হওয়া উচিত। আমি কি ভুল করছি?
ভোরেস

1
ছেদটি সেট করুন: sort set1 set2 | uniq -dমাল্টি-সেটের জন্য কাজ করে না। ব্যবহার বিবেচনা করুন sort <(sort -u set1) <(sort -u set2) | uniq -d
নিও

11

প্রকার, রকম. আপনার নিজের বাছাইয়ের সাথে মোকাবিলা commকরতে হবে , তবে প্রতিটি লাইনকে একটি সেট সদস্য হিসাবে বিবেচনা করে: -12ছেদ করার -13জন্য, পার্থক্যের জন্য এটি ব্যবহার করতে পারেন । (এবং -23আপনাকে set2 - set1পরিবর্তিত পার্থক্য দেয়, তার পরিবর্তে set1 - set2)) ইউনিয়ন sort -uএই সেটআপটিতে রয়েছে।


1
প্রকৃতপক্ষে, কম্ বেশিরভাগ স্টাফ করে। যদিও যুক্তিগুলি খুব অনিচ্ছাকৃত। ধন্যবাদ!
নীল্টন

7

আমি একটি নির্দিষ্ট সরঞ্জাম জানি না তবে আপনি পাইথন এবং এটির সেট ক্লাস এবং অপারেটরগুলি ব্যবহার করতে পারেন এটি করার জন্য একটি ছোট স্ক্রিপ্ট লিখতে।

উদাহরণের জন্য:

Python> s1 = set(os.listdir("/bin"))
Python> s2 = set(os.listdir("/usr/bin"))
Python> s1 & s2

set(['awk',
     'basename',
     'chroot', ...

হ্যাঁ, সুন্দর উত্তর। পাইথন পাওয়া গেলে কেন বিশ্রী ব্যবহার করবেন?
গেটল্লি

আপনি ভুলে গেছেন:Python> import os
জেমস বওয়ারি

7

ছোট কনসোল সরঞ্জাম "সেটআপ" এখন 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


3

আপনি যদি কোনও ফাইলকে লাইনের সেট হিসাবে দেখেন এবং ফাইলগুলি বাছাই করা থাকে তবে তা রয়েছে comm

আপনি যদি কোনও ফাইলকে (বহু) লাইনের সেট হিসাবে দেখেন এবং লাইনগুলি সাজানো grepনা হয় তবে পার্থক্য এবং ছেদটি করতে পারে (এটি নির্ধারিত পার্থক্য এবং ছেদটি অর্জন করে তবে মাল্টিসেটের জন্য গণনাকে সম্মান করে না)। ইউনিয়ন ঠিক cat

grep -xF -f small large >intersection
grep -vxF -f small large >difference
cat small large >union

2

আমি একটি পাইথন ইউটিলিটি তৈরি করেছি যা লাইন ওয়াইন ইউনিয়ন, ছেদ, পার্থক্য এবং একাধিক ফাইলের পণ্য করতে পারে। একে সেটওপ বলা হয়, আপনি এটি পাইপিআইতে খুঁজে পেতে পারেন ( এখানে )। সিনট্যাক্স এর মতো দেখাচ্ছে:

$ setop -i file1 file2 file3  # intersection
$ setop -d file1 file2 file3  # difference

1

এটি করার জন্য আমি একটি ছোট সরঞ্জাম লিখেছিলাম যা বিভিন্ন জায়গায় আমার পক্ষে বেশ কার্যকর। ইউআই অপরিশোধিত এবং খুব বড় ফাইলগুলির পারফরম্যান্স বৈশিষ্ট্য সম্পর্কে আমি নিশ্চিত নই (যেহেতু এটি পুরো তালিকাটি মেমরির মধ্যে পড়ে) তবে "এটি আমার পক্ষে কাজ করে"। প্রোগ্রামটি https://github.com/nibrahim/lines এ রয়েছে । এটা পাইথনে আপনি এটি ব্যবহার করে পেতে পারেন pip install lines

এটি বর্তমানে ইউনিয়ন, ছেদ, পার্থক্য এবং দুটি ফাইলের প্রতিসম পার্থক্য সমর্থন করে। ইনপুট ফাইলের প্রতিটি লাইন একটি সেট উপাদান হিসাবে বিবেচনা করা হয়।

এটিতে দুটি অতিরিক্ত অপারেশনও রয়েছে। একটি ফাইলের মধ্যে ফাঁকা লাইনগুলি বের করে নিন এবং দ্বিতীয়টি (যা আমার পক্ষে খুব দরকারী) ফাইলটি সন্ধান করা এবং এটি একই স্ট্রিংয়ের সেটে বিভক্ত করা। সাধারণ প্যাটার্নের সাথে মেলে না এমন একটি তালিকায় থাকা ফাইলগুলি অনুসন্ধান করার জন্য আমার এটি দরকার ছিল।

আমি প্রতিক্রিয়া স্বাগত জানাই।


0

ফাইল সিস্টেমটি ফাইলের নামগুলি (পাথ সহ পুরো ফাইলের নাম) অনন্য হিসাবে বিবেচনা করে।

অপারেশনস?

নতুন, ইউনিয়ন সেট পেতে আপনি খালি ডিরেক্টরি সি / তে ফাইলগুলি একটি এবং এবং বি / তে অনুলিপি করতে পারেন।

ফাইল-পরীক্ষার মতো -e nameএবং লুপগুলি বা সন্ধানের সাহায্যে আপনি দুটি বা ততোধিক ডিরেক্টরিতে থাকা ফাইলগুলি ছেদ করতে বা পার্থক্যটি পরীক্ষা করতে পারেন।


1
আমি বোঝাতে চাইছি ফাইলের বিষয়বস্তুগুলিকে একটি সেটের উপাদান হিসাবে ধরা যাক (যাক, প্রতি লাইন প্রতি একটি উপাদান) এবং ফাইলগুলি সেগুলি হিসাবে সেট করে।
নিলটন

0

এখানে সেরা উত্তর: সেটডাউন (একটি উত্সর্গীকৃত সরঞ্জাম)

আমি সেটডাউন নামক একটি প্রোগ্রাম লিখেছিলাম যা ক্লায়েন্ট থেকে সেট অপারেশন করে।

এটি মেকফাইলে আপনি যা লিখবেন তার অনুরূপ সংজ্ঞা লিখে সেট অপারেশন সম্পাদন করতে পারে:

someUnion: "file-1.txt" \/ "file-2.txt"
someIntersection: "file-1.txt" /\ "file-2.txt"
someDifference: someUnion - someIntersection

এটি বেশ দুর্দান্ত এবং আপনার এটি পরীক্ষা করা উচিত। আমি ব্যক্তিগতভাবে অ্যাড-হক কমান্ডগুলি ব্যবহার করার পরামর্শ দিচ্ছি না যেগুলি সেট অপারেশনগুলি সম্পাদনের জন্য কাজের জন্য তৈরি করা হয়নি you যখন আপনাকে সত্যিকার অর্থে অনেকগুলি সেট অপারেশন করার দরকার হয় বা যদি আপনার একে অপরের উপর নির্ভর করে এমন কোনও সেট অপারেশন থাকে তবে এটি কার্যকর হবে না t । কেবল এটিই নয় তবে সেটডাউন আপনাকে সেট অপারেশনগুলি লিখতে দেয় যা অন্যান্য সেট অপারেশনগুলির উপর নির্ভর করে!

যে কোনও হারে, আমি মনে করি এটি বেশ দুর্দান্ত এবং আপনার এটি সম্পূর্ণরূপে পরীক্ষা করা উচিত।


0

একাধিক ফাইলের জন্য নমুনা প্যাটার্ন (এই ক্ষেত্রে ছেদটি):

eval `perl -le 'print "cat ",join(" | grep -xF -f- ", @ARGV)' t*`

এতে প্রসারিত:

cat t1 | grep -xF -f- t2 | grep -xF -f- t3

পরীক্ষা ফাইলগুলি:

seq 0 20 | tee t1; seq 0 2 20 | tee t2; seq 0 3 20 | tee t3

আউটপুট:

0
6
12
18

0

সঙ্গে 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]}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.