দুটি বা ততোধিক ফাইল সহ ডিরেক্টরি


11

আমি বর্তমান ডিরেক্টরিটির একটি উপ-ডিরেক্টরি খুঁজে পেতে চাই, যা (এটি উপ-ডিরেক্টরি) 2 বা ততোধিক নিয়মিত ফাইল রয়েছে।

আমি 2 টিরও কম ফাইল সম্বলিত ডিরেক্টরিগুলিতে আগ্রহী নই, কেবলমাত্র ডিরেক্টরিতে কেবল সাব-ডাইরেক্টরিগুলিতে নেই।

উত্তর:


12

জিএনইউ findএবং এর উপর ভিত্তি করে এখানে সম্পূর্ণ আলাদা পদ্ধতির রয়েছে uniq। শেল কমান্ড নির্বাহের উপর ভিত্তি করে দেওয়া উত্তরগুলির তুলনায় এটি আরও দ্রুত এবং অনেকগুলি সিপিইউ-বান্ধব যা প্রতিটি ডিরেক্টরিতে পাওয়া ফাইলগুলির জন্য গণনা করে।

find . -type f -printf '%h\n' | sort | uniq -d

findকমান্ড অনুক্রমের সব ফাইল নির্দেশিকা ছাপে এবং uniqশুধুমাত্র ডিরেক্টরি যে দুইবার কমপক্ষে প্রদর্শিত প্রদর্শন করা হয়।


2
আপনার আউটপুট বিশ্লেষণ করা উচিত নয় find। এই ক্ষেত্রে, কারণ জিএনইউ findবর্তমান ডিরেক্টরিতে মুদ্রণযোগ্য নয় এমন অক্ষরের রয়েছে এমন ডিরেক্টরিগুলির নাম ছড়িয়ে দেবে (সি লোকালে "ä" এর মতো)। এছাড়াও দেখুন unix.stackexchange.com
জিজ্ঞাসা /

4
@ কুসালানন্দ, যখন আউটপুট টিটিটিতে না যায় not এখানে, কেবলমাত্র নতুন সমস্যাটি নতুন লাইনের চরিত্রগুলির সাথে, যা ব্যবহার করে আপনি ঠিক করতে পারবেন-printf '%h\0' | sort -z | uniq -zd | xargs -r0 ...
স্টাফেন চেজেলাস

6
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 বা তার বেশি ছিল কিনা to এই পরীক্ষার ফলাফল হ'ল স্ক্রিপ্টের রিটার্ন মান (প্রস্থান স্থিতি)।

যদি পরীক্ষাটি সফল হয়, তবে ডিরেক্টরিটির পাথ মুদ্রণ -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

আপনার সমাধানটি বিন্দু দিয়ে শুরু হওয়া কোনও ফাইল দিয়ে ফাইল গণনা করে না। যে কোনও ডিরেক্টরি নেই এমন ডিরেক্টরিগুলির সাথে ত্রুটি বার্তাগুলি এড়ানোর জন্য আপনার সি = 0 টি সূচনা করা উচিত।
xhienne

@ শিহেনে আমি লুকানো ফাইল বিবেচনা করেছি এবং এটি সম্পর্কে একটি নোট যুক্ত করব। [ "" -ge 2 ]বৈধ পরীক্ষা হওয়ার কারণে কোনও ডিরেক্টরিতে নিয়মিত ফাইল না থাকলে কোনও ত্রুটি নেই ।
কুসালানন্দ

আপনি কীভাবে "বৈধ" সংজ্ঞা দেবেন তা নিশ্চিত নন। POSIX এর পূর্ণসংখ্যার মান হতে arg1 প্রয়োজন। dash, bash --posixএবং testসমস্ত একটি ত্রুটি বার্তা প্রদর্শন করে 2 (যেমন "একটি ত্রুটি ঘটেছে") দিয়ে
বেরিয়ে যায়

@ শিহেনে আহ, আমি এমন একটি সিস্টেমে পরীক্ষা করছিলাম যা এখন kshচলছে sh। অবিলম্বে সংশোধন করবে। আমার দিকে তাকানোর জন্য ধন্যবাদ! :-)
কুসালানন্দ

এছাড়াও, [ -f ... ]প্রতীকী লিঙ্কগুলি dereferences। এগুলি নির্মূল করার জন্য আপনার একটি পরীক্ষা করা উচিত কারণ প্রশ্নটি নির্দিষ্ট করে যে কেবল নিয়মিত ফাইলগুলি গণনা করা উচিত।
xhienne

6

সাহায্যে গিলেজ এর উত্তর উপর 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

আমার প্রথমে এটি ছিল, তবে আপনার একাধিক সাব-ডাইরেক্টরি এবং ফাইল যুক্ত ডিরেক্টরিতে সমস্যা হবে । এটি কেবলমাত্র সাবডাইরেক্টরিগুলি সম্বলিত ডিরেক্টরিগুলিকে আগাছা ফেলে দেয় না।
Kusalananda

এটি সত্যিই এটি সমাধান করে না। এটি আমার পরীক্ষার সেটআপে testএবং dir2ডিরেক্টরিগুলি উভয়ই সন্ধান করে (আমার উত্তর দেখুন)।
Kusalananda

আপনার উদাহরণ জন্য কাজ করে, কিন্তু যোগ test/x1এবং test/x2ফাইল সেইসাথে ... $1এবং $2জন্য ডিরেক্টরি হতে হবে test, এবং ডিরেক্টরির মিস করা হবে।
Kusalananda

@ কুসালানন্দ আপনি যে উত্তর দিয়েছেন তার ব্যতীত আমি খুঁজে পাইনি, আমি আপনার কমান্ডের কিছু অংশ আপনার হুবহু ডুপ্লিকেট না হওয়ার জন্য পরিবর্তন করার চেষ্টা করেছি (আপনি যেমন লুকানো ফাইলগুলি বাদ দিয়েছিলেন না), আমার ক্ষমা চাই।
нιη

1
কোনও উদ্বেগ নেই :-)
কুসালানন্দ

3

অন্য 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 বা ততোধিক নিয়মিত ফাইল সহ সাবফোল্ডার নাম / পাথ মুদ্রণ করুন

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