উত্তর:
জিএনইউতে find
আপনি এর জন্য -printf
প্যারামিটার ব্যবহার করতে পারেন , যেমন:
find /dir1 -type f -printf "%f\n"
-o
চেয়ে কম অগ্রাধিকার রয়েছে -a
, তাই আপনি প্রায়শই নিজের -o
যুক্তি গোষ্ঠী করতে চান )
ব্যবহার করুন -execdir
যা স্বয়ংক্রিয়ভাবে বর্তমান ফাইলটিকে ধারণ করে {}
, উদাহরণস্বরূপ:
find . -type f -execdir echo '{}' ';'
আপনি এর $PWD
পরিবর্তেও ব্যবহার করতে পারেন .
(কিছু সিস্টেমে এটি সামনে কোনও অতিরিক্ত বিন্দু তৈরি করে না)।
যদি আপনি এখনও অতিরিক্ত বিন্দু পেয়ে থাকেন তবে বিকল্পভাবে আপনি চালাতে পারেন:
find . -type f -execdir basename '{}' ';'
-execdir utility [argument ...] ;
-execdir
প্রাথমিক অভিন্ন-exec
ব্যতিক্রম যে ইউটিলিটি যে ডিরেক্টরি থেকে কার্যকর করা হবে প্রাথমিক বর্তমান ফাইলটি ঝুলিতে ।
+
পরিবর্তে ব্যবহার করা হয় ;
, তারপরে {}
ইউটিলিটির প্রতিটি অনুরোধের জন্য যতটা সম্ভব পথের নাম দ্বারা প্রতিস্থাপন করা হয়। অন্য কথায়, এটি সমস্ত ফাইলের নাম এক লাইনে মুদ্রণ করবে।
./filename
পরিবর্তে পাচ্ছি filename
। আপনার প্রয়োজনের উপর নির্ভর করে, এটি ঠিক আছে বা নাও পারে।
$PWD
পরিবর্তে চেষ্টা করুন .
।
আপনি যদি জিএনইউ ব্যবহার করেন তবে সন্ধান করুন
find . -type f -printf "%f\n"
অথবা আপনি একটি প্রোগ্রামিং ভাষা ব্যবহার করতে পারেন যেমন রুবি (১.৯+)
$ ruby -e 'Dir["**/*"].each{|x| puts File.basename(x)}'
যদি আপনি কোনও ব্যাশ (কমপক্ষে 4) সমাধান কল্পনা করেন
shopt -s globstar
for file in **; do echo ${file##*/}; done
আপনি যদি কেবল ফাইলের বিরুদ্ধে কিছু পদক্ষেপ নিতে চান তবে ব্যবহার basename
করা শক্ত হতে পারে।
উদাহরণস্বরূপ:
find ~/clang+llvm-3.3/bin/ -type f -exec echo basename {} \;
শুধু বেসনাম প্রতিধ্বনিত হবে /my/found/path
। আমরা যদি ফাইলের নামে চালাতে চাই তবে আমরা যা চাই তা নয়।
কিন্তু আপনি তারপর xargs
আউটপুট করতে পারেন । উদাহরণস্বরূপ অন্য একটি দিরের নামের উপর ভিত্তি করে একটি ডিয়ারে ফাইলগুলি হত্যা করা:
cd dirIwantToRMin;
find ~/clang+llvm-3.3/bin/ -type f -exec basename {} \; | xargs rm
find ~/clang+llvm-3.3/bin/ -type f -exec basename {} \;
-exec
এবং -execdir
ধীর, xargs
রাজা।
$ alias f='time find /Applications -name "*.app" -type d -maxdepth 5'; \
f -exec basename {} \; | wc -l; \
f -execdir echo {} \; | wc -l; \
f -print0 | xargs -0 -n1 basename | wc -l; \
f -print0 | xargs -0 -n1 -P 8 basename | wc -l; \
f -print0 | xargs -0 basename | wc -l
139
0m01.17s real 0m00.20s user 0m00.93s system
139
0m01.16s real 0m00.20s user 0m00.92s system
139
0m01.05s real 0m00.17s user 0m00.85s system
139
0m00.93s real 0m00.17s user 0m00.85s system
139
0m00.88s real 0m00.12s user 0m00.75s system
xargs
এর সমান্তরালতাও সাহায্য করে।
মজাদারভাবে যথেষ্ট আমি xargs
ছাড়া শেষ ঘটনাটি ব্যাখ্যা করতে পারি না -n1
। এটি সঠিক ফলাফল দেয় এবং এটি দ্রুততম¯\_(ツ)_/¯
( basename
কেবলমাত্র 1 টি পাথ আর্গুমেন্ট নেয় তবে xargs
সেগুলি পাঠিয়ে দেবে (আসলে 5000)) -n1
লিনাক্স এবং ওপেনবিএসডি তে কাজ করে না, কেবলমাত্র ম্যাকোস ...)
কীভাবে -execdir
সহায়তা করে তা দেখতে একটি লিনাক্স সিস্টেম থেকে কিছু বড় সংখ্যা , তবে সমান্তরালের তুলনায় এখনও অনেক ধীর xargs
:
$ alias f='time find /usr/ -maxdepth 5 -type d'
$ f -exec basename {} \; | wc -l; \
f -execdir echo {} \; | wc -l; \
f -print0 | xargs -0 -n1 basename | wc -l; \
f -print0 | xargs -0 -n1 -P 8 basename | wc -l
2358
3.63s real 0.10s user 0.41s system
2358
1.53s real 0.05s user 0.31s system
2358
1.30s real 0.03s user 0.21s system
2358
0.41s real 0.03s user 0.25s system
find
এটি হ'ল -execdir
দ্রুততর হয়ে ওঠে কারণ নতুন প্রক্রিয়া তৈরি করা তুলনামূলক ব্যয়বহুল অপারেশন।
সত্যিই basename
এবং dirname
সমাধানগুলি সহজ, তবে আপনি এটিও পরীক্ষা করে দেখতে পারেন:
find . -type f | grep -oP "[^/]*$"
অথবা
find . -type f | rev | cut -d '/' -f1 | rev
অথবা
find . -type f | sed "s/.*\///"
অন্যরা যেমন নির্দেশ করেছে, আপনি একত্রিত করতে পারেন find
এবং basename
, কিন্তু ডিফল্টরূপে basename
প্রোগ্রামটি একবারে কেবলমাত্র একটি পাথে কাজ করবে, সুতরাং প্রতিটি পাথের জন্য একবারে এক্সিকিউটেবল চালু করতে হবে (হয় ব্যবহার করে find ... -exec
বাfind ... | xargs -n 1
), এটি সম্ভবত ধীর হতে পারে।
আপনি যদি -a
বিকল্পটি ব্যবহার করে থাকেন basename
, তবে এটি একক অনুরোধে একাধিক ফাইলের নাম গ্রহণ করতে পারে, যার অর্থ আপনি সেইগুলি xargs
ছাড়াই ব্যবহার করতে পারবেন -n 1
, পাথগুলিকে আরও কম সংখ্যক প্রার্থনার জন্য একসাথে ভাগ করতে basename
, যা আরও কার্যকর হতে হবে।
উদাহরণ:
find /dir1 -type f -print0 | xargs -0 basename -a
এখানে আমি অন্তর্ভুক্ত করেছি -print0
-0
ফাইল এবং ডিরেক্টরিগুলির নামের ভিতরে যে কোনও শ্বেত স্পেসের সাথে লড়াই করতে ( এবং যা একসাথে ব্যবহার করা উচিত) ।
সংস্করণ xargs basename -a
এবং xargs -n1 basename
সংস্করণগুলির মধ্যে এখানে একটি সময়ের তুলনা । (মত-তুলনার মতো, এখানে রিপোর্ট করা সময়গুলি প্রাথমিক ডামি রান করার পরে, যাতে ফাইল মেটাডেটা ইতিমধ্যে I / O ক্যাশে অনুলিপি করার পরে উভয়ই সম্পন্ন হয়।) আমি আউটপুটটি পাইপ করেছি cksum
উভয় ক্ষেত্রেই কেবল প্রদর্শিত হয় যে আউটপুটটি ব্যবহৃত পদ্ধতির থেকে পৃথক।
$ time sh -c 'find /usr/lib -type f -print0 | xargs -0 basename -a | cksum'
2532163462 546663
real 0m0.063s
user 0m0.058s
sys 0m0.040s
$ time sh -c 'find /usr/lib -type f -print0 | xargs -0 -n 1 basename | cksum'
2532163462 546663
real 0m14.504s
user 0m12.474s
sys 0m3.109s
আপনি দেখতে পাচ্ছেন, basename
প্রতিবারের প্রবর্তনটি এড়াতে এটি যথেষ্ট পরিমাণে দ্রুততর ।
basename
অতিরিক্ত কোনও কমান্ড-লাইন আর্গুমেন্টের প্রয়োজন ছাড়াই একাধিক ফাইলের নাম গ্রহণ করা হবে। এখানে ব্যবহার -a
লিনাক্স এ। ( basename --version
আমাকে বলে basename (GNU coreutils) 8.28
।)