जवाबों:
यहाँ GNU पर आधारित find
और पूरी तरह से अलग दृष्टिकोण है uniq
। यह एक शेल कमांड को निष्पादित करने के आधार पर उत्तर की तुलना में बहुत तेज और बहुत सीपीयू-अनुकूल है जो प्रत्येक निर्देशिका के लिए फ़ाइलों की गणना करता है।
find . -type f -printf '%h\n' | sort | uniq -d
find
आदेश पदानुक्रम में सभी फाइलों की सूची प्रिंट और uniq
केवल निर्देशिका कि दो बार कम से कम दिखाई देते हैं प्रदर्शित करता है।
-printf '%h\0' | sort -z | uniq -zd | xargs -r0 ...
find . -type d \
-exec sh -c 'c=0; for n in "$1"/*; do [ -f "$n" ] && [ ! -h "$n" ] && c=$(( c + 1 )); done; [ "$c" -ge 2 ]' sh {} ';' \
-print
यह वर्तमान निर्देशिका में या उसके नीचे सभी नामों को खोजेगा और फिर उन सभी नामों को फ़िल्टर करेगा जो निर्देशिकाओं के नाम नहीं हैं।
शेष निर्देशिका नाम इस लघु लिपि को दिए जाएंगे:
c=0
for n in "$1"/*; do
[ -f "$n" ] && [ ! -h "$n" ] && c=$(( c + 1 ))
done
[ "$c" -ge 2 ]
यह स्क्रिप्ट पहले कमांड लाइन तर्क (से find
) के रूप में दी गई निर्देशिका में नियमित फाइलों (प्रतीकात्मक लिंक्स को छोड़ना) की संख्या की गणना करेगी । स्क्रिप्ट में अंतिम कमांड यह देखने के लिए एक परीक्षण है कि क्या गिनती 2 या अधिक थी। इस परीक्षण का परिणाम स्क्रिप्ट का रिटर्न मान (निकास स्थिति) है।
यदि परीक्षण सफल हुआ, तो निर्देशिका के लिए मार्ग का प्रिंट आउट किया -print
जाएगा find
।
छिपी हुई फ़ाइलों पर विचार करने के लिए (फाइलें जिनके नाम डॉट से शुरू होते हैं), sh -c
स्क्रिप्ट को कहने से बदल दें
for n in "$1"/*; do
सेवा
for n in "$1"/* "$1"/.*; do
परिक्षण:
$ tree
.
`-- test
|-- a
|-- dir1
| |-- a
| |-- b
| `-- c
`-- dir2
|-- dira
|-- dirb
| |-- file-1
| `-- file-2
`-- dirc
6 directories, 6 files
$ find . -type d -exec sh -c 'c=0; for n in "$1"/*; do [ -f "$n" ] && [ ! -h "$n" ] && c=$(( c + 1 )); done; [ "$c" -ge 2 ]' sh {} ';' -print
./test/dir1
./test/dir2/dirb
[ "" -ge 2 ]
मान्य परीक्षण है, तो निर्देशिका में कोई नियमित फ़ाइलें नहीं हैं, तो कोई त्रुटि नहीं है।
dash
, bash --posix
और test
सभी एक त्रुटि संदेश प्रदर्शित करते हैं और 2 के साथ बाहर निकलते हैं (यानी "एक त्रुटि हुई")
ksh
रूप में चल रहा था sh
। तुरंत संशोधन करेंगे। मुझ पर प्रहार करने के लिए धन्यवाद! :-)
[ -f ... ]
dereferences प्रतीकात्मक लिंक। आपको उन्हें समाप्त करने के लिए एक परीक्षण जोड़ना चाहिए क्योंकि सवाल निर्दिष्ट करता है कि केवल नियमित फ़ाइलों को गिना जाना चाहिए।
की मदद से गाइल्स के जवाब पर SU और उसके रिवर्स और कुछ संशोधन, यहाँ आप क्या जरूरत है।
find . -type d -exec sh -c 'set -- "$1"/*;X=0;
for args; do [ -f "$args" ] && X=$((X+1)) ;done; [ "$X" -gt 1 ] ' _ {} \; -print
निर्देशिका पेड़।
.
├── test
│ ├── dir1
│ │ ├── a
│ │ ├── b
│ │ └── c
│ ├── dir2
│ │ ├── dira
│ │ │ └── a file\012with\012multiple\012line
│ │ ├── dirb
│ │ │ ├── file-1
│ │ │ └── file-2
│ │ └── dirc
│ ├── diraa
│ ├── dirbb
│ ├── dircc
│ └── x
│ └── x1
│ └── x2
└── test2
├── dir3
└── dir4
परिणाम:
./test
./test/dir1
./test/dir2/dirb
test
और dir2
अपने परीक्षण सेटअप में निर्देशिका (मेरा उत्तर देखें)।
test/x1
और test/x2
फ़ाइलों के रूप में रूप में अच्छी तरह ... $1
और $2
के लिए निर्देशिका हो जाएगा test
, और निर्देशिका छूट जाएँगी।
एक और find
+ wc
दृष्टिकोण:
find path/currdir -maxdepth 1 -type d ! -empty ! -path "path/currdir" \
-exec sh -c 'count=$(find "$1" -maxdepth 1 -type f | wc -l); [ $count -ge 2 ]' _ {} \; -print
path/currdir
- अपने वर्तमान निर्देशिका के लिए पथ
-maxdepth 1
- केवल प्रत्यक्ष बाल सबफ़ोल्डर्स पर विचार करें
! -empty
- खाली सबफोल्डर्स को नजरअंदाज करें
! -path "path/currdir"
- वर्तमान निर्देशिका पथ पर ध्यान न दें
count=$(find "$1" -maxdepth 1 -type f | wc -l)
- count
प्रत्येक पाया सबफ़ोल्डर के लिए फ़ाइलों की संख्या के साथ सौंपा गया है
[ $count -ge 2 ] ... -print
- प्रिंट सबफ़ोल्डर नाम / पथ जिसमें 2 या अधिक नियमित फाइलें हों
find
। इस मामले में, क्योंकि जीएनयूfind
उन निर्देशिकाओं के नामों को संकलित करेगा जिनके पास वर्तमान लोकेल में मुद्रण योग्य नहीं हैं (जैसे सी लोकेल में "ä")। यह भी देखें unix.stackexchange.com/questions/321697/...