অনুলিপি ফাইল-নামের ক্ষেত্রে সংবেদনশীল অনুসন্ধান


17

কেসিং (আপার-কেস এবং / বা লোয়ার-কেস) নির্বিশেষে ডুপ্লিকেট ফাইলের নাম সহ একটি ডিরেক্টরিতে সমস্ত ফাইল সন্ধান করার উপায় আছে?

উত্তর:


14

আপনার যদি জিএনইউ ইউটিলিটিগুলি (বা কমপক্ষে একটি সেট যা শূন্য-সমাপ্ত লাইনগুলি নিয়ে কাজ করতে পারে) উপলভ্য থাকে তবে অন্য উত্তরের একটি দুর্দান্ত পদ্ধতি রয়েছে:

find . -maxdepth 1 -print0 | sort -z | uniq -diz

দ্রষ্টব্য: আউটপুটটিতে শূন্য-সমাপ্ত স্ট্রিং থাকবে; আপনি আরও প্রক্রিয়া করার জন্য যে সরঞ্জামটি ব্যবহার করেন তা এটি পরিচালনা করতে সক্ষম হওয়া উচিত।

শূন্য-সমাপ্ত লাইনগুলিকে মোকাবেলা করে এমন সরঞ্জামগুলির অভাবে বা আপনি যদি নিশ্চিত করতে চান যে আপনার কোড এমন পরিবেশে কাজ করছে যেখানে এই জাতীয় সরঞ্জাম উপলব্ধ নেই, আপনার একটি ছোট স্ক্রিপ্ট দরকার:

#!/bin/sh
for f in *; do
  find . -maxdepth 1 -iname ./"$f" -exec echo \; | wc -l | while read count; do
    [ $count -gt 1 ] && echo $f
  done
done

এ কী পাগলামি? পাগল ফাইল নামগুলির জন্য এটি নিরাপদ করে এমন কৌশলগুলির ব্যাখ্যার জন্য এই উত্তরটি দেখুন ।


1
আমি কেবল একটি অনুরূপ পোস্ট করতে যাচ্ছিলাম ... তবে আরও খারাপ উত্তর :)
রোজসিটারজেভিয়াকজ

2
আপনার কি সত্যিই দরকার -mindepth?
rozcietrzewiacz

আমি সোলারিস ব্যবহার করছি। আপনি / ইউএসআর / বিন / আপনি যেটির কথা বলছেন তা কি খুঁজে পাচ্ছেন? আমি এটি ব্যবহার করার চেষ্টা করেছি এবং আমাকে অনেক ত্রুটি দিয়েছি।
লামক্রো

@ ইলেমক্রো নো, সোলারিস জিএনইউ ব্যবহার করে না find; একটি উত্তর- GNU সমাধান অন্তর্ভুক্ত করার জন্য আমি উত্তরটি সম্পাদনা করেছি।
শন জে গফ 21

ঠিক আছে. আমি কি কেবল এটি কোনও পাঠ্য ফাইলে পেস্ট করব এবং এটিকে কার্যকর করার অধিকার দেব?
লামক্রো

12

উপরে অনেক জটিল উত্তর রয়েছে, এটি সবার চেয়ে সহজ এবং দ্রুত বলে মনে হচ্ছে:

find . -maxdepth 1 | sort -f | uniq -di

আপনি যদি সাব-ডিরেক্টরিতে নকল ফাইলের নামগুলি সন্ধান করতে চান তবে আপনাকে কেবল পুরো নামটি নয়, কেবল ফাইলের নামটির তুলনা করতে হবে:

find . -maxdepth 2 -printf "%f\n" | sort -f | uniq -di

সম্পাদনা করুন: শন জে গফ নির্দেশ করেছেন যে আপনার যদি নিউলাইন চরিত্রের ফাইলের নাম থাকে তবে এটি ব্যর্থ হবে। আপনি যদি জিএনইউ ইউটিলিটিগুলি ব্যবহার করে থাকেন তবে আপনি এই কাজগুলিও করতে পারেন:

find . -maxdepth 1 -print0 | sort -fz | uniq -diz

-print0(খোঁজ) ও -zবিকল্প তাদের কারণ NUL-সমাপ্ত স্ট্রিং উপর কাজ করতে (সাজানোর এবং Uniq জন্য), পরিবর্তে সম্পর্কে newline সমাপ্ত স্ট্রিং। যেহেতু ফাইলের নামগুলিতে NUL থাকতে পারে না, এটি সমস্ত ফাইলের নামের জন্য কাজ করে।


1
তবে শন জে গফের জবাব সম্পর্কে আমার মন্তব্য দেখুন, আপনি সন্ধানের--প্রিন্ট0 বিকল্পটি এবং ইউনিট এবং সাজানোর জন্য -z বিকল্পটি যুক্ত করতে পারেন। এছাড়াও, আপনি চাই - সাজানোর পাশাপাশি। তারপরে এটি কাজ করে। (আমি আপনার উত্তরে এটি সম্পাদনা করতে যাচ্ছি, আপনি অনুমোদন না দিলে ফিরে যেতে
নির্দ্বিধায়

শেষ কমান্ডটি আমাকে গাড়ীর রিটার্ন ছাড়াই আউটপুট দিচ্ছে (ফলাফল সবই এক লাইনে থাকে)। কমান্ডটি চালানোর জন্য আমি রেড হ্যাট লিনাক্স ব্যবহার করছি। প্রথম কমান্ড লাইনটি আমার পক্ষে সবচেয়ে ভাল কাজ করে।
সূর্যের

2

কেস-সংবেদনশীল উপায়ে ফাইলের নামের তালিকাটি সাজান এবং নকল মুদ্রণ করুন। sortকেস-সংবেদনশীল বাছাইয়ের জন্য একটি বিকল্প রয়েছে। জিএনইউও করে uniq, তবে অন্যান্য বাস্তবায়ন নয় এবং আপনি যা করতে পারেন তা uniqহ'ল প্রথম উপাদানটিকে বাদ দিয়ে ডুপ্লিকেটগুলির সেটগুলিতে প্রতিটি উপাদান মুদ্রণ করা। জিএনইউ সরঞ্জামগুলির সাহায্যে, ধরে নেওয়া যে কোনও ফাইলের নামের একটি নতুন লাইন নেই, ডুপ্লিকেটগুলির প্রতিটি সেটে একটি উপাদান ছাড়াও সমস্ত উপাদান মুদ্রণের সহজ উপায় রয়েছে:

for x in *; do printf "%s\n" "$x"; done |
sort -f |
uniq -id

বহনযোগ্যভাবে, নকলের প্রতিটি সেটে সমস্ত উপাদান মুদ্রণ করার জন্য, ধরে নেওয়া উচিত যে কোনও ফাইলের নামের মধ্যে একটি নতুন লাইন নেই:

for x in *; do printf "%s\n" "$x"; done |
sort -f |
awk '
    tolower($0) == tolower(prev) {
        print prev;
        while (tolower($0) == tolower(prev)) {print; getline}
    }
    1 { prev = $0 }'

আপনি যদি নতুন লাইনের সমন্বিত ফাইলের নামগুলি সমন্বিত করতে চান তবে পার্ল বা পাইথনের জন্য যান। নোট করুন যে আপনাকে আউটপুটটি ঝাপটানো বা আরও ভালভাবে একই ভাষাতে আরও প্রক্রিয়াকরণ করার দরকার হতে পারে, যেমন নীচের নমুনা কোডটি নিজস্ব আউটপুটে আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা আলাদা নতুন নাম ব্যবহার করে।

perl -e '
    foreach (glob("*")) {push @{$f{lc($_)}}, $_}
    foreach (keys %f) {@names = @{$f{$_}}; if (@names > 1) {print "$_\n" foreach @names}}
'

এখানে একটি খাঁটি zsh সমাধান। এটি কিছুটা ভার্বোজ, কারণ ডুপ্লিকেট উপাদানগুলিকে অ্যারে বা গ্লোব ফলাফলের মধ্যে রাখার কোনও অন্তর্নির্মিত উপায় নেই।

a=(*)(N); a=("${(@io)a}")
[[ $#a -le 1 ]] ||
for i in {2..$#a}; do
  if [[ ${(L)a[$i]} == ${(L)a[$((i-1))]} ]]; then
    [[ ${(L)a[$i-2]} == ${(L)a[$((i-1))]} ]] || print -r $a[$((i-1))]
    print -r $a[$i]
  fi
done

1

জিএনইউ ছাড়া find:

LANG=en_US ls | tr '[A-Z]' '[a-z]' | uniq -c | awk '$1 >= 2 {print $2}'


2
trযে কোনও চরিত্রের সেটটিতে চরিত্রের জন্য একক বাইটের বেশি ব্যবহার করা হয়, তাতে ধ্বংসের সম্ভাবনা খুব বেশি। ইউটিএফ -8 এর প্রথম প্রথম 256 টি অক্ষর ব্যবহারের সময় নিরাপদ tr। থেকে উইকিপিডিয়া TR (ইউনিক্স) .. অধিকাংশই সংস্করণ trগনুহ সহ, trএবং ক্লাসিক ইউনিক্স tr, একক বাইটের থেকে কাজ এবং ইউনিকোড অনুবর্তী নয় ..
Peter.O

1
আমার আগের মন্তব্যে আপডেট করুন .. ইউটিএফ -8 এর প্রথম প্রথম 128 টি অক্ষরই নিরাপদ। অর্ডিনাল রেঞ্জের উপরের সমস্ত ইউটিএফ -8 অক্ষর 0..127 সমস্ত মাল্টি-বাইট এবং অন্যান্য অক্ষরে স্বতন্ত্র বাইট মান থাকতে পারে। কেবলমাত্র 0..127 রেঞ্জের বাইটগুলির একটি অনন্য চরিত্রের সাথে এক থেকে এক সংযোগ রয়েছে।
পিটার.ও

প্লাসের uniqএকটি কেস-সংবেদনশীল পতাকা রয়েছে i।
জেমি কিটসন

1

অবশেষে আমি এটিকে পরিচালনা করেছি:

find . | tr '[:upper:]' '[:lower:]' | sort | uniq -d

আমি কারণের findপরিবর্তে ব্যবহার করেছি lsআমার সম্পূর্ণ পথ প্রয়োজন (প্রচুর উপ-ডিরেক্টরি) অন্তর্ভুক্ত। এটি দিয়ে কীভাবে করব তা আমি খুঁজে পাইনি ls


2
উভয় sortএবং uniqযথাক্রমে এফ-আই এবং উপেক্ষা-কেস পতাকা রয়েছে।
জ্যামি কিটসন

-1

তারপরে যে কেউ এই ফাইলটির একটির নাম পরিবর্তন করতে চান তার জন্য:

find . -maxdepth 1 | sort -f | uniq -di | while read f; do echo mv "$f" "${f/.txt/_.txt}"; done
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.