বাশের দুটি তালিকার ছেদ ছেয়ে গেছে


163

আমি একটি সাধারণ স্ক্রিপ্ট লেখার চেষ্টা করছি যা দুটি তালিকায় থাকা বিষয়বস্তুগুলিকে তালিকাভুক্ত করবে। সরল করতে, আসুন উদাহরণ হিসাবে ls ব্যবহার করি। "এক" এবং "দুটি" ডিরেক্টরিগুলি কল্পনা করুন।

one = `ls one``
two = `ls two`
ছেদ $ এক $ দুই

আমি এখনও ব্যাশে বেশ সবুজ, তাই আমি কীভাবে এটি করছি তা সংক্ষিপ্ত মনে করুন। আমার শুধু কিছু কমান্ড দরকার যা "এক" এবং "দুটি" এ সমস্ত ফাইল মুদ্রণ করবে। তারা উভয়ই থাকতে হবে। আপনি এটিকে "এক" এবং "দুটি" এর মধ্যে "ছেদ" বলতে পারেন।


এখানে কিছুই আসলে প্রশ্নের উত্তর দেয় না: কীভাবে বাশ স্ক্রিপ্টে দুটি ভেরিয়েবল ছেদ করতে হয় ।
জামেসফিশার

আমার মতে একটি নতুন প্রশ্নের মতো মনে হচ্ছে, এখানে সেই প্রশ্নের স্পষ্ট উত্তর দেওয়া হয়েছে।
জিন-ক্রিস্টোফ মেল্লাউড

একটি তর্কসাপেক্ষে আরো উপযোগী পদ্ধতির মধ্যে কাছাকাছি সদৃশ stackoverflow.com/questions/2312762/...
tripleee

উত্তর:


285
comm -12  <(ls 1) <(ls 2)

37
বিশ্বাস করতে পারি না commআজ অবধি আমার কোন জ্ঞান ছিল না । এটি আমার পুরো সপ্তাহটি সবেমাত্র তৈরি করেছে :)
দারাগ এনরাট

22
commইনপুটগুলি বাছাই করা প্রয়োজন। এই ক্ষেত্রে, lsস্বয়ংক্রিয়ভাবে এর আউটপুটটি সাজান, তবে অন্যান্য ব্যবহারের জন্য এটি করা দরকার হতে পারে:comm -12 <(some-command | sort) <(some-other-command | sort)
আলেকজান্ডার বার্ড

11
কোনও কিছুর জন্য আউটপুট ব্যবহার করবেন না। ls ডিরেক্টরি মেটাডেটা ইন্টারেক্টিভভাবে দেখার জন্য একটি সরঞ্জাম। কোড সহ এলএস আউটপুট পার্সিংয়ের যে কোনও প্রচেষ্টা নষ্ট হয়ে গেছে। গ্লোবগুলি অনেক বেশি সহজ এবং সঠিক: '' টেক্সট ফাইলের জন্য ''। Mywiki.wooledge.org/ParsingLs
র্যানি আলবেগ ওয়েইন

2
আমি এটি ব্যবহার করে একটি বৈশিষ্ট্য দ্বারা সরবরাহিত কোনও publicপদ্ধতির ব্যবহারের সন্ধান করতে চেষ্টা করেছি error(), এর সাথে মিশ্রণে git grepএবং এটি দুর্দান্ত ছিল! আমি দৌড়ে এসেছি $ comm -12 <(git grep -il "\$this->error(" -- "*.php") <(git grep -il "Dash_Api_Json_Response" -- "*.php")এবং ভাগ্যক্রমে আমি কেবল ফাইলটির নাম দিয়েছি যা কেবল বৈশিষ্ট্য ধারণ করে।
লোকালহেইঞ্জ

3
এই অত্যধিক হাসিখুশি. আমি অ্যাজকে দিয়ে কিছু ক্রেজি স্টাফ করার চেষ্টা করছিলাম।
রলফ

55

সঙ্গে সমাধান comm

commদুর্দান্ত তবে প্রকৃতপক্ষে সাজানো তালিকার সাথে কাজ করা দরকার। এবং ভাগ্যক্রমে এখানে আমরা ব্যাশ ম্যান পৃষ্ঠা lsথেকে যা ব্যবহার করিls

এন্ট্রিগুলিকে বর্ণমালিকভাবে বাছাই করুন -কুফ্টুঅ্যাক্স এবং না -র মতো না হলে।

comm -12  <(ls one) <(ls two)

সঙ্গে বিকল্প sort

দুটি তালিকার ছেদ:

sort <(ls one) <(ls two) | uniq -d

দুটি তালিকার প্রতিসাম্যগত পার্থক্য:

sort <(ls one) <(ls two) | uniq -u

বোনাস

এটার সাথে খেলো ;)

cd $(mktemp -d) && mkdir {one,two} && touch {one,two}/file_{1,2}{0..9} && touch two/file_3{0..9}

2
পরিপূরক পরিবর্তে , আমি মনে করি এটাকেই সাধারণত প্রতিসম পার্থক্য বলা হয় ।
অ্যান্ড্রু লাজার

29

commকমান্ডটি ব্যবহার করুন :

ls one | sort > /tmp/one_list
ls two | sort > /tmp/two_list
comm -12 /tmp/one_list /tmp/two_list

"সাজানোর" আসলেই প্রয়োজন হয় না তবে "কম" ব্যবহারের আগে আমি সর্বদা এটি অন্তর্ভুক্ত করি।


5
এটি অন্তর্ভুক্ত করা ভাল কারণ এটি বাছাই করার দরকার নেই এবং তিনি উদাহরণ হিসাবে কেবলমাত্র ls ব্যবহার করেছেন।
Thor84no

3

একটি কম দক্ষ (কম থেকে) বিকল্প:

cat <(ls 1 | sort -u) <(ls 2 | sort -u) | uniq -d

1
আপনাকে আপনার স্ক্রিপ্টের মধ্যে ডেবিয়ান এর / বিন / ড্যাশ অথবা অন্য কোনো অ ব্যাশ শেল ব্যবহার করে থাকেন, আপনি শৃঙ্খল কমান্ড 'আউটপুট প্রথম বন্ধনী ব্যবহার করতে পারেন: (ls 1; ls 2) | sort -u | uniq -d
নাইট্রোজেন

1
@ মিকাআলমায়ার আপনি যে ব্যক্তিকে জবাব দিচ্ছেন তার নামটি আপনার পতাকাঙ্কিত করা উচিত, নইলে ধারণা করা হয় আপনি আমার বোঝাতে চাইছেন।
বেনুবার্ড

@ নাইট্রোজেন মিকাউলমায়ার সঠিক - চ্যাং করা sort -u | uniq -dকিছুই করে না, কারণ ইউনিকের খোঁজ শুরু করার আগেই সাজ্টটি সদৃশগুলি সরিয়ে ফেলেছে। আমি মনে করি আপনি আমার আদেশ যা করছেন তা বুঝতে পারেন নি।
বেনুবার্ড

@ বেনুবার্ড আমি আপনার আদেশটি কোনওরকম cat <(ls 1 | sort -u) <(ls 2 | sort -u) | uniq -dআউটপুট এনে দিতে সক্ষম হইনি। আমার আদেশ পড়া উচিত (ls 1; ls 2) | sort | uniq -dছাড়াই -uতালিকা ছেদ দেখানোর জন্য। @ মিকাআলমায়ার ঠিক বলেছেন যে আমার মূল কমান্ডটি ভেঙে গেছে।
নাইট্রোজেন

@ নাইট্রোজেন যে কারণে আমি বিড়ালটি ব্যবহার করছি তা হ'ল এটি আমি একটি সাধারণ সমাধান হতে চাই, যাতে আপনি lsঅন্য কোনও কিছু দিয়ে প্রতিস্থাপন করতে পারেন find। আপনার সমাধান এটির অনুমতি দেয় না, কারণ কোনও আদেশ যদি দুটি লাইন একই করে দেয় তবে এটি এটিকে সদৃশ হিসাবে তুলে নিয়েছে p ব্যবহারকারী ls 1/*উপ-ডিরেক্টরিতে সমস্ত ফাইলের তুলনা করতে এবং তুলনা করতে চাইলেও আমার কাজ করে । অন্যথায়, হ্যাঁ, এটি কাজ করে। এটি আমার পক্ষে বাশ-নির্দিষ্ট possible
বেনুবার্ড

2

যোগদান ইনপুট এবং পছন্দসই আউটপুট উপর নির্ভর করে আরেকটি ভাল বিকল্প

join -j1 -a1 <(ls 1) <(ls 2)

-1

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

# List1=( 0 1 2 3 4   6 7 8 9 10 11 12)
# List2=(   1 2 3   5 6   8 9    11 )
# List3=($(comm -12 <(echo ${List1[*]}| tr " " "\n"| sort) <(echo ${List2[*]} | tr " " "\n"| sort)| sort -g))
# echo ${List3[*]}
1 2 3 6 8 9 11

কম ইউটিলিটি একটি বর্ণানুক্রমিক বাছাই করে, যেখানে "ব্যাশের ইন অ্যারে ছেদ" উত্তরগুলি ব্যবহার করে; সুতরাং "সাজান" এবং "বাছাই-জি" ব্যবহার।

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