আমি জানি **/*.ext
সমস্ত উপ-ডিরেক্টরিগুলি মিলে থাকা সমস্ত ফাইলে বিস্তৃত হয় *.ext
, তবে বর্তমান ডিরেক্টরিতে এই জাতীয় সমস্ত ফাইল অন্তর্ভুক্ত করার সাথে একটি অনুরূপ প্রসারণ কী?
উত্তর:
এটি বাশ 4 এ কাজ করবে:
ls -l {,**/}*.ext
ডাবল অস্ট্রিক গ্লোব কাজ করার জন্য, globstar
বিকল্পটি সেট করতে হবে (ডিফল্ট: চালু):
shopt -s globstar
থেকে man bash
:
গ্লোবস্টার যদি সেট করা থাকে তবে ফাইলের নাম বিস্তৃত কোণে ব্যবহৃত প্যাটার্ন ** পাঠ্যটি একটি ফাইল এবং শূন্য বা আরও ডিরেক্টরি এবং এর সাথে মেলে উপ-ডিরেক্টরি যদি প্যাটার্নটি একটি / দ্বারা অনুসরণ করা হয় তবে কেবল ডিরেক্টরি এবং উপ-ডিরেক্টরি মেলে।
এখন আমি ভাবছি যে যদি গ্লোবস্টার প্রসেসিংয়ে কোনও সময় বাগ থাকতে পারে, কারণ এখন সহজভাবে ব্যবহার করে ls **/*.ext
আমি সঠিক ফলাফল পাচ্ছি।
নির্বিশেষে, আমি ভিএলসি সংগ্রহস্থলটি ব্যবহার করে বিশ্লেষণ কেনোরবকে দেখেছি এবং সেই বিশ্লেষণে এবং আমার উত্তরটিতে তত্ক্ষণাত উপরে কিছু সমস্যা পেয়েছি:
find
কমান্ডের ফলাফলের সাথে তুলনাগুলি অবৈধ কারণ নির্দিষ্টকরণে -type f
অন্যান্য ফাইল প্রকার (বিশেষত ডিরেক্টরি) অন্তর্ভুক্ত করা হয়নি এবং ls
তালিকাভুক্ত কমান্ডগুলি সম্ভবত এটি করে না। এছাড়াও, তালিকাভুক্ত কমান্ডগুলির মধ্যে একটি ls -1 {,**/}*.*
- যা উপরের খনিতে ভিত্তি করে বলে মনে হচ্ছে, কেবল এমন নামগুলি আউটপুট করে যা এই ডিরেক্টরিগুলিতে সাব-ডিরেক্টরিতে অন্তর্ভুক্ত রয়েছে for ওপির প্রশ্ন এবং আমার উত্তরে একটি বিন্দু অন্তর্ভুক্ত রয়েছে যেহেতু যা চাওয়া হচ্ছে তা একটি নির্দিষ্ট বর্ধনের ফাইল with
তবে সবচেয়ে গুরুত্বপূর্ণ, ls
গ্লোবস্টার প্যাটার্ন সহ কমান্ডটি ব্যবহার করে একটি বিশেষ সমস্যা রয়েছে **
। অনেকগুলি সদৃশ উদ্ভূত হয়েছে যেহেতু প্যাটার্নটি বাশ দ্বারা গাছের সমস্ত ফাইলের নাম (এবং ডিরেক্টরি নাম) এ প্রসারিত করা হয়েছে examined সম্প্রসারণের পরে ls
কমান্ড তাদের প্রতিটি এবং তাদের বিষয়বস্তু ডিরেক্টরিতে তালিকাভুক্ত করে যদি তালিকাভুক্ত হয়।
উদাহরণ:
আমাদের বর্তমান ডিরেক্টরিতে সাব-ডিরেক্টরি A
এবং এর বিষয়বস্তু রয়েছে:
A
└── AB
└── ABC
├── ABC1
├── ABC2
└── ABCD
└── ABCD1
সেই গাছে, **
"এএ / এবি এ / এবি / এবিসি এ / এবি / এবিসি / এবিসি 1 এ / এবি / এবিসি / এবিসি 2 এ / এবি / এবিসি / এবিসিডি এ / এবি / এবিসি / এবিসিডি / এবিসিডি 1" (7 টি প্রবেশ) । যদি আপনি echo **
এটি করেন তবে সঠিক আউটপুট আপনি পাবেন এবং প্রতিটি প্রবেশ একবারে উপস্থাপন করা হবে। যাইহোক , আপনি যদি ls **
এটি প্রবেশ করে প্রতিটি প্রবেশের একটি তালিকা আউটপুট । সুতরাং মূলত এটি ls A
অনুসরণ করে ls A/AB
, ইত্যাদি, তাই A/AB
দুইবার প্রদর্শিত হয়। এছাড়াও, ls
প্রতিটি উপ-ডিরেক্টরি এর আউটপুট পৃথক সেট করতে চলেছে:
...
<blank line>
directory name:
content-item
content-item
সুতরাং wc -l
সেই সমস্ত ফাঁকা লাইন এবং ডিরেক্টরি নাম বিভাগের শিরোনামগুলি গণনা করে যা গণনা আরও দূরে সরিয়ে দেয়।
এটি আপনাকে বিশ্লেষণls
না করার আরও একটি কারণ ।
এই আরও বিশ্লেষণের ফলস্বরূপ, আমি এই পদ্ধতিতে ফাইলের গাছের উপরে পুনরাবৃত্তি করা ছাড়া অন্য কোনও পরিস্থিতিতে গ্লোবস্টার প্যাটার্নটি ব্যবহার না করার পরামর্শ দিচ্ছি:
for entry in **
do
something "$entry"
done
চূড়ান্ত তুলনা হিসাবে, আমি আমার হাতে ব্যাশ উত্সের সংগ্রহস্থল ব্যবহার করেছি এবং এটি করেছি:
shopt -s globstar dotglob
diff <(echo ** | tr ' ' '\n') <(find . | sed 's|\./||' | sort)
0a1
> .
আমি tr
শূন্যস্থানগুলিকে নতুন লাইনে পরিবর্তন করতাম যা কেবলমাত্র বৈধ যেহেতু কোনও নাম ফাঁক করে না। আমি আউটপুট প্রতিটি লাইন থেকে sed
নেতৃস্থানীয় অপসারণ ব্যবহৃত । আমি আউটপুটটি বাছাই করেছিলাম যেহেতু এটি সাধারণত আনসোর্টড হয় না এবং বাশের গ্লোবগুলির সম্প্রসারণ ইতিমধ্যে বাছাই করা হয়। আপনি দেখতে পাচ্ছেন, কেবলমাত্র একমাত্র আউটপুট ছিল বর্তমান ডিরেক্টরি আউটপুট দ্বারা । আমি যখন আউটপুট প্রায় দ্বিগুণ লাইন ছিল।./
find
find
diff
.
find
ls ** | wc -l
globstar
খেলাপি হয়ে পড়েছিoff
**/*.ext
যদিও যথেষ্ট হওয়া উচিত। এছাড়াও, আপনি না থাকলে আপনার কাছে লুকানো ফাইল থাকবে না shopt -s dotglob
।
globstar
: shopt -u globstar
।
**/*.ext
যথেষ্ট হবে না
এটি বর্তমান ডিরেক্টরি এবং এর উপ-ডিরেক্টরিগুলির সমস্ত ফাইল মুদ্রণ করবে যা '.ext' এ শেষ হয়।
find . -name '*.ext' -print
আপনি ব্যবহার করতে পারেন: **/*.*
পুনরাবৃত্তভাবে সমস্ত ফাইল অন্তর্ভুক্ত করতে (এর দ্বারা সক্ষম করুন shopt -s globstar
)।
অন্যান্য বৈচিত্রগুলি এবং তারা কীভাবে আচরণ করে তা দয়া করে নীচে পরীক্ষা করুন।
নমুনা ভিএলসি সংগ্রহস্থল ফোল্ডারে 3472 ফাইল সহ ফোল্ডারটি পরীক্ষা করা হচ্ছে :
(3472 এর মোট ফাইলগুলি গণনা করা হয়েছে find . -type f | wc -l
:)
ls -1 **/*.*
- 3338 প্রদান করেls -1 {,**/}*.*
- ফেরত 3341 ( ডেনিস প্রস্তাবিত হিসাবে )ls -1 {,**/}*
- 8265 ফেরত দেয়ls -1 **/*
- লুকানো ফাইলগুলি ( ডেনিস প্রস্তাবিত হিসাবে ) বাদে 7817 প্রদান করেls -1 **/{.[^.],}*
- ফেরত দেয় 7869 ( ডেনিস প্রস্তাবিত হিসাবে )ls -1 {,**/}.?*
- 15855 প্রদান করেls -1 {,**/}.*
- 20321 ফেরত দেয়সুতরাং আমি মনে করি সমস্ত ফাইলকে পুনরাবৃত্তির সাথে তালিকাবদ্ধ করার সর্বাধিক নিকটতম পদ্ধতিটি হ'ল gniourf-gniourf মন্তব্য অনুসারে ( **/*.*
) ফাইলগুলির যথাযথ এক্সটেনশন রয়েছে বা নির্দিষ্টটি ব্যবহার করে ধরে নেওয়া), যেমন দ্বিতীয় উদাহরণটি নীচের মতো আরও কয়েকটি নকল দেয় :
$ diff -u <(ls -1 {,**/}*.*) <(ls -1 **/*.*)
--- /dev/fd/63 2015-04-19 15:25:07.000000000 +0100
+++ /dev/fd/62 2015-04-19 15:25:07.000000000 +0100
@@ -1,6 +1,4 @@
COPYING.LIB
-COPYING.LIB
-Makefile.am
Makefile.am
@@ -45,7 +43,6 @@
compat/tdestroy.c
compat/vasprintf.c
configure.ac
-configure.ac
এবং অন্যটি আরও নকল তৈরি করে।
লুকানো ফাইলগুলি অন্তর্ভুক্ত করতে, ব্যবহার করুন: shopt -s dotglob
(এর দ্বারা অক্ষম করুন shopt -u dotglob
)। এটি প্রস্তাবিত নয়, কারণ এটি কমান্ডগুলিকে প্রভাবিত করতে পারে mv
বা rm
আপনি এবং দুর্ঘটনাক্রমে ভুল ফাইলগুলি মুছতে পারেন।
**/*.*
তথ্যবহুল) খুঁজে পেয়েছি এবং সবচেয়ে ভাল কাজ করেছি। গৃহীত উত্তরের কারণে শীর্ষ ডিরেক্টরিতে থাকা আইটেমের সদৃশ হয়েছিল। আমার কাজের ধরণটি ছিল:"${path}"**/*.*
$ find . -type f
এটি বর্তমান ডিরেক্টরিতে সমস্ত ফাইলের তালিকা প্রদর্শন করবে। তারপরে আপনি -exec ব্যবহার করে আউটপুটটিতে আরও কিছু কমান্ড করতে পারেন
$find . -type f -exec grep "foo" {} \;
এটি "foo" স্ট্রিংয়ের জন্য প্রতিটি ফাইল গ্রেপ করবে will
find . -type f
কেবল বর্তমান ডিরেক্টরিতে নয়, কেবল বর্তমান ডিরেক্টরিতেও মূল ডিরেক্টরিটিতে পুনরাবৃত্তভাবে প্রযোজ্য।
বর্তমান ডিরেক্টরিটি অন্তর্ভুক্ত করার জন্য কেন কেবল ব্রেস সম্প্রসারণ ব্যবহার করবেন না?
./{*,**/*}.ext
গ্লোব সম্প্রসারণের আগে ব্রেস প্রসারণ ঘটে তাই আপনি পুরানো সংস্করণের বাশ দিয়ে কার্যকরভাবে যা করতে চান তা করতে পারেন এবং নতুন সংস্করণগুলিতে গ্লোবস্টারের সাথে বানর রাখতে পারেন।
এছাড়াও, ./
আপনার গ্লোব নিদর্শনগুলিতে শীর্ষস্থানীয় অন্তর্ভুক্ত করার জন্য এটি ব্যাশের ভাল অনুশীলন হিসাবে বিবেচিত ।
**/*.ext
। আপনি কি নিশ্চিত যে এটি আপনার পক্ষে কাজ করে?