जवाबों:
यदि आपके पास GNU उपयोगिताओं (या कम से कम एक सेट जो शून्य-समाप्त लाइनों से निपट सकता है) उपलब्ध है, तो एक अन्य उत्तर में एक महान सेवा है:
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
ये क्या पागलपन हे? इस उत्तर को उन तकनीकों की व्याख्या के लिए देखें जो पागल फाइलनाम के लिए इसे सुरक्षित बनाती हैं।
-mindepth
?
find
; मैंने गैर-जीएनयू समाधान को शामिल करने के लिए उत्तर को संपादित किया है।
ऊपर कई जटिल जवाब हैं, यह उन सभी की तुलना में सरल और तेज लगता है:
find . -maxdepth 1 | sort -f | uniq -di
यदि आप उपनिर्देशिकाओं में डुप्लिकेट फ़ाइल नाम ढूंढना चाहते हैं, तो आपको केवल फ़ाइल नाम की तुलना करने की आवश्यकता है, न कि संपूर्ण पथ:
find . -maxdepth 2 -printf "%f\n" | sort -f | uniq -di
संपादित करें: शॉन जे। गोफ ने इंगित किया है कि यदि आप नए वर्णों के साथ फ़ाइल नाम रखते हैं तो यह विफल हो जाएगा। यदि आप GNU उपयोगिताओं का उपयोग कर रहे हैं, तो आप ये काम भी कर सकते हैं:
find . -maxdepth 1 -print0 | sort -fz | uniq -diz
-print0
(खोज के लिए) और -z
विकल्प जिसके कारण ये NUL-समाप्त तारों पर काम करने के लिए (प्रकार और uniq के लिए), के बजाय न्यू लाइन समाप्त तार। चूँकि फ़ाइल नाम में NUL नहीं हो सकता है, यह सभी फ़ाइल नामों के लिए काम करता है।
केस-असंवेदनशील तरीके से फ़ाइल नामों की सूची को क्रमबद्ध करें और डुप्लिकेट प्रिंट करें। sort
केस-असंवेदनशील छँटाई के लिए एक विकल्प है। तो जीएनयू uniq
, लेकिन अन्य कार्यान्वयन नहीं है, और आप जो कुछ भी कर सकते हैं uniq
वह हर तत्व को डुप्लिकेट के एक सेट में प्रिंट करता है, पहले को छोड़कर। GNU टूल के साथ, यह मानते हुए कि किसी फ़ाइल नाम में कोई नई पंक्ति नहीं है, सभी तत्वों को प्रिंट करने का एक आसान तरीका है लेकिन डुप्लिकेट के प्रत्येक सेट में एक:
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 }'
यदि आपको नए नामों वाली फ़ाइल नामों को समायोजित करने की आवश्यकता है, तो पर्ल या पायथन के लिए जाएं। ध्यान दें कि आपको आउटपुट को ट्विक करने की आवश्यकता हो सकती है, या अपनी आगे की प्रक्रिया को उसी भाषा में करना चाहिए, क्योंकि नीचे दिया गया नमूना कोड अपने स्वयं के आउटपुट में अलग-अलग नामों के लिए newlines का उपयोग करता है।
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
GNU के बिना find
:
LANG=en_US ls | tr '[A-Z]' '[a-z]' | uniq -c | awk '$1 >= 2 {print $2}'
tr
है बहुत किसी भी वर्ण सेट जो चरित्र प्रति एक एकल बाइट की तुलना में अधिक का उपयोग करता है पर कहर बरपा की संभावना है। उपयोग करते समय केवल UTF-8 के पहले 256 अक्षर सुरक्षित हैं tr
। से विकिपीडिया टीआर (यूनिक्स) .. के अधिकांश संस्करणों tr
जीएनयू सहित, tr
और क्लासिक यूनिक्स tr
, एकल बाइट्स पर काम करते हैं और यूनिकोड अनुरूप नहीं हैं ..
uniq
में एक केस-असंवेदनशील झंडा है i।
मैंने अंत में इसे इस तरह से प्रबंधित किया:
find . | tr '[:upper:]' '[:lower:]' | sort | uniq -d
मैंने find
इसके बजाय इसका उपयोग किया ls
क्योंकि मुझे पूर्ण पथ (बहुत सारे उपनिर्देशिका) की आवश्यकता थी। मुझे नहीं लगा कि मैं यह कैसे कर सकता हूं ls
।
sort
और uniq
क्रमशः फ्लैग-केस फ्लैग, एफ और आई हैं।
किसी और के लिए जो फिर से नाम बदलना चाहता है आदि में से एक फाइल:
find . -maxdepth 1 | sort -f | uniq -di | while read f; do echo mv "$f" "${f/.txt/_.txt}"; done