কোনও পাঠ্য ফাইল অন্যটির উপসেট কিনা তা কীভাবে জানবেন


12

আমি কোনও পাঠ্য ফাইল অন্যটির উপসেট কিনা তা নির্ধারণের জন্য একটি উপায় অনুসন্ধান করার চেষ্টা করছি ..

উদাহরণ স্বরূপ:

foo
bar

এর একটি উপসেট

foo
bar
pluto

যদিও:

foo
pluto

এবং

foo
bar

একে অপরের সাবসেট নয় ...

কমান্ড দিয়ে এটি করার কোনও উপায় আছে?

এই চেকটি অবশ্যই ক্রস চেক হওয়া উচিত এবং এটির ফিরে আসতে হবে:

file1 subset of file2 :    True
file2 subset of file1 :    True
otherwise             :    False

সম্ভাব্য আরও কার্যকর সমাধান (যদি ফাইলগুলিও অর্ডার করা হয়): github.com/barrycarter/bcapps/blob/master/…
ব্যারিকার্টার

উত্তর:


11

ঐ ফাইলের বিষয়বস্তু বলা হয় যদি file1, file2এবং file3apearance ক্রমানুসারে তাহলে আপনি এটি নিম্নলিখিত এক-লাইনের সঙ্গে করতে পারেন:

 # python -c "x=open('file1').read(); y=open('file2').read(); print x in y or y in x"
 True
 # python -c "x=open('file2').read(); y=open('file1').read(); print x in y or y in x"
 True
 # python -c "x=open('file1').read(); y=open('file3').read(); print x in y or y in x"
 False

আপনার উত্তরের জন্য ধন্যবাদ .. +1 .. আমি জানি না আমার উত্তরটি গ্রহণ করুন কিনা কারণ আপনার ইউনিক্স-লিনাক্স নির্দিষ্ট নয় এবং আমার উত্তরটি কিছুটা দ্রুত, যতদূর আমি এটি পরীক্ষা করেছি .. আপনি কী ভাবেন?
gc5

আপনি স্বাগতম, আরও ইউনিক্স নির্দিষ্ট সরঞ্জাম সহ অন্যান্য সমাধান অবশ্যই আছে। তবে পাইথনের inঅপারেটরের এটি ভাল ব্যবহার বলে মনে হচ্ছে ।
টিমো

পাইপ নামক পাইপ ইন, আরও ইউনিক্স তৈরি করার জন্য পাইথন কমান্ড লাইন র‌্যাপার রয়েছে: কোড. google.com.com/p/pyp আমি মনে করি একটি লাইনারের সরঞ্জামের মতো এই সমাধানটিকে আরও ইউনিক্স করা তুচ্ছ।
আইবিআর

3

সহ perl:

if perl -0777 -e '$n = <>; $h = <>; exit(index($h,$n)<0)' needle.txt haystack.txt
then echo needle.txt is found in haystack.txt
fi

-0octalরেকর্ড সীমানা সংজ্ঞা দেয়। যখন অষ্টাল সংখ্যাটি 0377 (সর্বাধিক বাইট মান) এর চেয়ে বেশি হয়, তার অর্থ কোনও ডিলিমিটার নেই, এটি করার সমতুল্য $/ = undef। সেক্ষেত্রে, <>একটি একক ফাইলের পূর্ণ কন্টেন্ট, যে ফেরৎ গবগব করে খাওয়া মোড

আমাদের দু'বার $hএবং $nভেরিয়েবলগুলিতে ফাইলগুলির বিষয়বস্তু উপস্থিত হয়ে গেলে আমরা index()একটি অপরটিতে পাওয়া যায় কিনা তা নির্ধারণ করতে ব্যবহার করতে পারি ।

তবে এর অর্থ এই যে পুরো ফাইলগুলি মেমরিতে সঞ্চয় করা হয় যার অর্থ এই পদ্ধতিটি খুব বড় ফাইলগুলির জন্য কাজ করবে না।

এমএম্পেবল ফাইলগুলির জন্য (সাধারণত নিয়মিত ফাইল এবং সর্বাধিক সন্ধানযোগ্য ফাইলগুলি যেমন ব্লক ডিভাইসগুলি অন্তর্ভুক্ত করে) এর mmap()জন্য Sys::Mmapপার্ল মডিউলটির মতো ফাইলগুলি ব্যবহার করে কাজ করা যেতে পারে :

if 
  perl -MSys::Mmap -le '
    open N, "<", $ARGV[0] || die "$ARGV[0]: $!";
    open H, "<", $ARGV[1] || die "$ARGV[1]: $!";
    mmap($n, 0, PROT_READ, MAP_SHARED, N);
    mmap($h, 0, PROT_READ, MAP_SHARED, H);
    exit (index($h, $n) < 0)' needle.txt haystack.txt
then
  echo needle.txt is found in haystack.txt
fi

2

আমি এই প্রশ্নের ধন্যবাদ একটি সমাধান পেয়েছি

মূলত আমি দুটি ফাইল পরীক্ষা করছি a.txtএবং b.txtএই স্ক্রিপ্টটি দিয়ে:

#!/bin/bash

first_cmp=$(diff --unchanged-line-format= --old-line-format= --new-line-format='%L' "$1" "$2" | wc -l)
second_cmp=$(diff --unchanged-line-format= --old-line-format= --new-line-format='%L' "$2" "$1" | wc -l)

if [ "$first_cmp" -eq "0" -o "$second_cmp" -eq "0" ]
then
    echo "Subset"
    exit 0
else
    echo "Not subset"
    exit 1
fi

অন্য একটি স্ক্রিপ্ট ফেরতের উপসেট হয়, তাহলে 0এর জন্য Trueঅন্যথায় 1


% এল কী করে? এই স্ক্রিপ্টটি কাজ করছে বলে মনে হচ্ছে না, এবং আমি এটি ডিবাগ করার চেষ্টা করছি ...
অ্যালেক্স

আমি আসলে এর অর্থটি মনে করি না %L, এটি তিন বছর আগে ছিল। থেকে man diff(বর্তমান সংস্করণ) %Lমানে হলো "লাইন বিষয়বস্তু"।
gc5

% এল "নতুন" লাইনের বিষয়বস্তু মুদ্রণ করে। IOW, অপরিবর্তিত রেখাগুলি বা পুরাতন লাইনগুলির জন্য কিছু মুদ্রণ করবেন না, তবে নতুন-লাইনের জন্য লাইনের সামগ্রীগুলি মুদ্রণ করুন।
পিএলজি

এই স্ক্রিপ্ট আমার জন্য কাজ করে, বাক্সের বাইরে!
পিএলজি

2

যদি f1 f2 এর উপসেট হয় তবে f1 - f2 একটি ফাঁকা সেট। এর উপর ভিত্তি করে আমরা একটি_সুবসেট ফাংশন এবং এটি থেকে প্রাপ্ত একটি ফাংশন লিখতে পারি। অনুযায়ী সেট পার্থক্য 2 পাঠ্য ফাইল মধ্যে


সাজ্ট_ফায়ালগুলি () {
  f1_sorted = "$ 1.sorted"
  f2_sorted = "$ 2.sorted"

  যদি [! -ফ $ এফ 1_সোর্টার্ড]; তারপর
    বিড়াল $ 1 | সাজানো | uniq> $ f1_ সাজানো
  ফাই

  যদি [! -f $ f2_sort]; তারপর
    বিড়াল $ 2 | সাজানো | uniq> $ f2_ সাজানো
  ফাই
}

সরান_সোর্টড ফাইলস () {
  f1_sorted = "$ 1.sorted"
  f2_sorted = "$ 2.sorted"
  rm -f $ f1_sorted
  rm -f $ f2_sorted
}

set_union () {
  বাছাই_ফায়ার্স $ 1 $ 2
  বিড়াল "$ 1. সাজানো" "$ 2. সাজানো" | সাজানো | uniq
  সরান_সোর্টড ফাইলগুলি $ 1 $ 2
}

সেট_ডিফ () {
  বাছাই_ফায়ার্স $ 1 $ 2
  বিড়াল "$ 1.sort" "" $ 2. রক্ষিত "" $ 2. সাজানো "| সাজানো | uniq -u
  সরান_সোর্টড ফাইলগুলি $ 1 $ 2
}

আরসেট_ডিফ () {
  বাছাই_ফায়ার্স $ 1 $ 2
  বিড়াল "$ 1. সাজানো" "$ 2. রক্ষিত" "$ 1. সাজানো" | সাজানো | uniq -u
  সরান_সোর্টড ফাইলগুলি $ 1 $ 2
}

is_subset () {
  বাছাই_ফায়ার্স $ 1 $ 2
  আউটপুট = $ (সেট_ডিফ $ 1 $ 2)
  সরান_সোর্টড ফাইলগুলি $ 1 $ 2

  যদি [-z $ আউটপুট]; তারপর
    ফিরে 0
  আর
    প্রত্যাবর্তন 1
  ফাই

}


এই স্ক্রিপ্ট দিয়ে শুরু করা উচিত #!/bin/bash?
অ্যালেক্স

2

Http://www.catonmat.net/blog/set-operation-in-unix- Shell / থেকে :

কম দুটি লাইনের মাধ্যমে দুটি বাছাই করা ফাইলের তুলনা করে। এটি এমনভাবে চালানো যেতে পারে যে এটি কেবল প্রথম নির্দিষ্ট ফাইলটিতে প্রদর্শিত লাইনগুলি আউটপুট করে। প্রথম ফাইলটি যদি দ্বিতীয়টির সাবসেট হয় তবে 1 ম ফাইলের সমস্ত লাইন 2 য়-তে উপস্থিত হয়, সুতরাং কোনও আউটপুট তৈরি হয় না:

$ comm -23 <(sort subset | uniq) <(sort set | uniq) | head -1
# comm returns no output if subset ⊆ set
# comm outputs something if subset ⊊ set
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.