কমান্ডটি "ফাইন্ড |" গ্রেপ 'ফাইলনাম' "" ফাইলের নাম "খুঁজে" এর চেয়ে এত ধীর?


10

আমি উভয় কমান্ড চেষ্টা করেছিলাম এবং কমান্ডটি find | grep 'filename' সহজ find 'filename' কমান্ডের চেয়ে অনেকগুণ ধীর হয় ।

এই আচরণের সঠিক ব্যাখ্যা কী হবে?


2
আপনি প্রতিটি ফাইল সন্ধানের সাথে তালিকাভুক্ত করছেন এবং তারপরে প্রক্রিয়াটিতে ডেটা গ্রেপ-এ প্রেরণ করছেন। এর নিজস্ব ব্যবহারের সাথে আপনি আউটপুট পার্স করার জন্য প্রতিটি তালিকাভুক্ত ফাইল গ্রেপ-এ পাস করার ধাপটি মিস করছেন missing এটি অতএব দ্রুত হবে।
রমন সাইলোপাল

কী অর্থে ধীর? কমান্ডগুলি সম্পূর্ণ করতে আলাদা পরিমাণ সময় নেয়?
কুসালানন্দ

1
আমি স্থানীয়ভাবে এটি পুনরুত্পাদন করতে পারি না। যদি কিছু হয় তবে তার time find "$HOME" -name '.profile'চেয়ে বেশি সময় রিপোর্ট করে time find "$HOME" | grep -F '.profile'। (17 এর বনাম 12 সেকেন্ড)।
কুসালানন্দ

2
@ জেনিফারএন্ডারসন আমি দু'বারই বারবার দৌড়েছি। 17 এবং 12 সেকেন্ড গড় হয়। এবং হ্যাঁ, grepতারতম্যটি findফলাফলের যে কোনও জায়গায় মিলবে, যেখানে এর সাথে find -nameমিল পাওয়া কেবল মিলবে (এই ক্ষেত্রে)।
কুসালানন্দ

2
হ্যাঁ, find filename দ্রুত হবে । আমি কিন্ডা ধরে নিয়েছিলাম যে এটি একটি টাইপো এবং ওপি বলতে বোঝায় find -name filename। সহ find filename, কেবলমাত্র filenameপরীক্ষা করা হবে (এবং কিছুই নয়)।
কুসালানন্দ

উত্তর:


11

(আমি findএখানে জিএনইউ ধরে নিচ্ছি )

ঠিক ব্যবহার করা হচ্ছে

find filename

হবে , দ্রুত হতে কারণ এটা শুধু ফিরে আসবে filename, অথবা ভিতরে নাম filenameযদি এটি একটি ডিরেক্টরি অথবা একটি ত্রুটি যদি এই নামের বর্তমান ডিরেক্টরির মধ্যে অস্তিত্ব ছিল না। এটি একটি খুব দ্রুত অপারেশন, এর মতো ls filename(তবে filenameডিরেক্টরি যদি পুনরাবৃত্ত হয় তবে ডিরেক্টরি হয়)।

বিপরীতে,

find | grep filename

বর্তমান ডিরেক্টরি এবং নীচে থেকে সমস্ত নামের findএকটি তালিকা তৈরি করার অনুমতি দেয় যা এরপরে ফিল্টার হবে। এটি অবশ্যই অনেক ধীর অপারেশন হবে।grep

আমি ধরে নিচ্ছি যে আসলে যা ছিল উদ্দেশ্য ছিল

find . -type f -name 'filename'

এটি filenameবর্তমান ডিরেক্টরি বা নীচের যে কোনও জায়গায় নিয়মিত ফাইলের নাম হিসাবে সন্ধান করবে ।

এটি তত দ্রুত (বা তুলনামূলক দ্রুত) হবে find | grep filenameতবে grepসমাধানটি filenameপ্রতিটি পাওয়া নামের পুরো পথের -path '*filename*'সাথে মিলবে , যা করবে তার সাথে একইভাবে find


বিভ্রান্তিটি কীভাবে findকাজ করে তার একটি ভুল বোঝাবুঝি থেকে আসে ।

ইউটিলিটিটি কয়েকটি পাথ নেয় এবং এই পাথগুলির নীচে সমস্ত নাম দেয়।

তারপরে আপনি বিভিন্ন পরীক্ষাগুলি ব্যবহার করে ফিরে আসা নামগুলি সীমাবদ্ধ করতে পারেন যা ফাইলের নাম, পথ, টাইমস্ট্যাম্প, ফাইলের আকার, ফাইলের প্রকার ইত্যাদি নিয়ে কাজ করতে পারে using

যখন তুমি বললে

find a b c

আপনি findতিনটি পথের অধীনে উপলব্ধ প্রতিটি নাম তালিকাবদ্ধ করতে বলেন a, bএবং c। বর্তমান ডিরেক্টরিটিতে যদি নিয়মিত ফাইলগুলির নাম হতে থাকে তবে এগুলি ফিরিয়ে দেওয়া হবে। যদি তাদের মধ্যে কোনও ডিরেক্টরিটির নাম হয়ে থাকে, তবে সেই ডিরেক্টরিতে এটি আরও সমস্ত নামের সাথে ফিরে আসবে।

যখন আমি করি

find . -type f -name 'filename'

এটি বর্তমান ডিরেক্টরিতে ( .) এবং নীচে সমস্ত নামের একটি তালিকা উত্পন্ন করে। তারপরে এটি নিয়মিত ফাইলগুলির মধ্যে নামগুলি সীমাবদ্ধ করে, যেমন ডিরেক্টরিগুলি নয় ইত্যাদি -type f। এরপর যে ম্যাচ নামের আরও সীমাবদ্ধতা হল filenameব্যবহার -name 'filename'। স্ট্রিংটি filenameকোনও ফাইলের নাম গ্লোব্বিং প্যাটার্ন হতে পারে, যেমন *.txt(কেবল এটি উদ্ধৃত করা মনে রাখবেন!)।

উদাহরণ:

নিম্নলিখিতটি .profileআমার হোম ডিরেক্টরিতে ডাকা ফাইলটি "সন্ধান" করে বলে মনে হচ্ছে :

$ pwd
/home/kk
$ find .profile
.profile

তবে প্রকৃতপক্ষে, এটি পথে সমস্ত নাম ফেরত দেয় .profile(কেবলমাত্র একটি নাম আছে, এবং এটি এই ফাইলটির)।

তারপরে আমি cdএক স্তর উপরে উঠে আবার চেষ্টা করব:

$ cd ..
$ pwd
/home
$ find .profile
find: .profile: No such file or directory

findকমান্ড এখন কোন পথ নামক খুঁজে পাচ্ছি না .profile

তবে, যদি আমি বর্তমান ডিরেক্টরিটি সন্ধান করতে পাই এবং তারপরে ফিরে আসা নামগুলি কেবল সীমাবদ্ধ করে রাখি তবে সেখান.profile থেকে এটি এটি খুঁজে পেতে পারে:

$ pwd
/home
$ find . -name '.profile'
./kk/.profile

1
find filenameকেবল টাইপ ডিরেক্টরি না filenameহলে (বা filenameটাইপ ডিরেক্টরিতে ছিল তবে তার কোনও প্রবেশ নেই) কেবল ফিরে আসবে
স্টাফেন চ্যাজেলাস

2

প্রযুক্তিবিহীন ব্যাখ্যা: একটি ভিড়ের মধ্যে জ্যাকের খোঁজ করা ভিড়ের প্রত্যেকের জন্য অনুসন্ধান করা এবং জ্যাক ব্যতীত সকল বিবেচনা থেকে বাদ দেওয়ার চেয়ে দ্রুত।


সমস্যাটি হ'ল ওপ আশা করছে জ্যাকের ভিড়ে একমাত্র ব্যক্তি। যদি তা হয় তবে তারা ভাগ্যবান। এটি ফাইল হিসাবে চিহ্নিত হলে বা ডিরেক্টরিতে ডিরেক্টরিতে সমস্ত নাম find jackতালিকাভুক্ত করবে । এটি কীভাবে কাজ করে তা একটি ভুল বোঝাবুঝি । jackjackfind
কুসালানন্দ

1

আমি এখনও সমস্যাটি বুঝতে পারি নি তবে আরও কিছু অন্তর্দৃষ্টি দিতে পারি।

কুসালানন্দের মতো find | grepকলটি আমার সিস্টেমে স্পষ্টভাবে দ্রুততর হয়েছে যা খুব একটা বোঝায় না। প্রথমে আমি ধরেছিলাম কোনও ধরণের বাফারিং সমস্যা; কনসোলে লেখাটি পরবর্তী ফাইলের নামটি পড়ার জন্য পরবর্তী সিস্টেলে সময় কমিয়ে দেয়। পাইপে লেখা খুব দ্রুত: প্রায় 40MiB / s এমনকি 32-বাইট লেখার জন্য (আমার বরং ধীর সিস্টেমে; 1 এমআইবি ব্লকের আকারের জন্য 300 এমআইবি / গুলি)। সুতরাং আমি ধরে নিয়েছি যে findপাইপ (বা ফাইল) এ লেখার সময় ফাইল সিস্টেমটি দ্রুত পড়তে পারে যাতে ফাইল পাথ পড়ার এবং কনসোলে লেখার দুটি ক্রিয়াকলাপ সমান্তরালে চলতে পারে (যা findএকক থ্রেড প্রক্রিয়া হিসাবে নিজেই করতে পারে না।

এটা findদোষ

দুটি কল তুলনা করা

:> time find "$HOME"/ -name '*.txt' >/dev/null

real    0m0.965s
user    0m0.532s
sys     0m0.423s

এবং

:> time find "$HOME"/ >/dev/null

real    0m0.653s
user    0m0.242s
sys     0m0.405s

দেখায় যা findঅবিশ্বাস্যভাবে বোকা কিছু করে (যা কিছু হোক না কেন)। এটি কার্যকর করার ক্ষেত্রে বেশ অযোগ্য হতে দেখা যাচ্ছে -name '*.txt'

ইনপুট / আউটপুট অনুপাতের উপর নির্ভর করতে পারে

আপনি মনে করতে find -nameপারেন যে যদি খুব কম লেখার দরকার পড়ে তবে তা জিতবে। তবে আইএসটি এর জন্য আরও বিব্রতকর হয়ে পড়ে find। 200K ফাইলের (পাইপ ডেটার 13M) বিপরীতে লেখার মতো কিছু না থাকলেও এটি হারাবে grep:

time find /usr -name lwevhewoivhol

findgrepযদিও হিসাবে দ্রুত হতে পারে

দেখা যাচ্ছে যে findএর মূর্খতা nameঅন্যান্য পরীক্ষায় প্রসারিত হয় না। পরিবর্তে একটি রেজেক্স ব্যবহার করুন এবং সমস্যাটি চলে গেছে:

:> time find "$HOME"/ -regex '\.txt$' >/dev/null     

real    0m0.679s
user    0m0.264s
sys     0m0.410s

আমার ধারণা এটি একটি বাগ হিসাবে বিবেচিত হতে পারে। কেউ বাগ রিপোর্ট দাখিল করতে ইচ্ছুক? আমার সংস্করণটি খুঁজে পাওয়া গেছে (জিএনইউ সন্ধানী) ৪.6.০


আপনার সময় কত পুনরাবৃত্তিযোগ্য? আপনি যদি -nameপ্রথমে পরীক্ষাটি করেন, তবে ডিরেক্টরি সামগ্রীতে ক্যাশে না হওয়ার কারণে এটি ধীর হতে পারে। (পরীক্ষা করার সময় -nameএবং -regexআমি দেখতে পাই যে তারা প্রায় একই সময় গ্রহণ করে, একবারে ক্যাশে প্রভাবটি বিবেচনা করা হয়ে গেলে অবশ্যই এটি কেবল ভিন্ন সংস্করণ হতে পারে find...)
স্মরণার্থে

@psmears অবশ্যই, আমি এই পরীক্ষাগুলি বেশ কয়েকবার করেছি। প্রথম উত্তরের আগে প্রশ্নের মন্তব্যেও ক্যাশিংয়ের সমস্যাটি উল্লেখ করা হয়েছে। আমার findসংস্করণটি খুঁজে পাওয়া গেছে (জিএনইউ সন্ধানকারী) ৪.6.০
হউক লেগেছে

যোগ করা -name '*.txt'ধীর হয়ে যায় কেন অবাক হওয়ার কারণ find? প্রতিটি ফাইলের নাম পরীক্ষা করে এটি অতিরিক্ত কাজ করতে হয়।
বার্মার 18

@ বারমার একদিকে এই অতিরিক্ত কাজ অত্যন্ত দ্রুত করা যায়। অন্যদিকে এই অতিরিক্ত কাজ অন্যান্য কাজকে সাশ্রয় করে। findকম ডেটা লিখতে হবে। এবং একটি পাইপে লিখন অনেক ধীর অপারেশন।
হউক লেগেইন

ডিস্কে লেখা খুব ধীর গতির, পাইপে লেখা এতটা খারাপ নয়, এটি কেবল একটি কার্নেল বাফারে অনুলিপি করে। আপনার প্রথম পরীক্ষায় লক্ষ করুন যে /dev/nullকোনওভাবে আরও বেশি লেখার সময় সিস্টেমের সময় কম ব্যবহৃত হয়েছে ।
বার্মার

0

বিজ্ঞপ্তি : আমি ধরে নেব যে আপনি বোঝাতে চেয়েছিলেন find . -name filename(অন্যথায়, আপনি বিভিন্ন জিনিস সন্ধান করছেন; find filenameআসলে ফাইল নাম নামে একটি পাথ অনুসন্ধান করেন , যার মধ্যে প্রায় কোনও ফাইল থাকতে পারে না, তাই খুব দ্রুতই উপস্থিত হয়)।


ধরুন আপনার কাছে পাঁচ হাজার ফাইল রয়েছে এমন একটি ডিরেক্টরি রয়েছে। বেশিরভাগ ফাইল সিস্টেমে, এই ফাইলগুলি আসলে একটি গাছের কাঠামোতে সংরক্ষণ করা হয় , যা প্রদত্ত যে কোনও ফাইল দ্রুত সনাক্ত করতে দেয়।

সুতরাং যখন আপনাকে জিজ্ঞাসা findএকটি ফাইল যার নাম শুধুমাত্র পরীক্ষণের প্রয়োজন সনাক্ত, findহবে জিজ্ঞাসা জন্য যে অন্তর্নিহিত ফাইলসিস্টেম, যা মাস স্টোরেজ থেকে খুব কম পৃষ্ঠাগুলি পড়তে হবে ফাইল, এবং শুধুমাত্র যে ফাইল। সুতরাং যদি ফাইল সিস্টেমটি এর নুনের মূল্য রাখে তবে সমস্ত এন্ট্রি পুনরুদ্ধার করতে এই গাছটি পুরো গাছটিকে অতিক্রম করার চেয়ে আরও দ্রুত চালিত হবে ।

আপনি যখন সরল findকথাটি জিজ্ঞাসা করেন তবে আপনি যা করেন ঠিক তেমন, আপনি পুরো গাছটি অতিক্রম করে পড়ছেন। প্রতি. একক। এন্ট্রি। বড় ডিরেক্টরিগুলির সাথে, এটি একটি সমস্যা হতে পারে (ঠিক এই কারণেই বেশ কয়েকটি সফ্টওয়্যার, ডিস্কে প্রচুর ফাইল সঞ্চয় করার জন্য, "ডিরেক্টরি গাছ" দুটি বা তিনটি গভীর গভীরতা তৈরি করবে: এইভাবে, প্রতিটি পাতায় কেবল কম কম রাখা দরকার নথি পত্র).


-2

ধরে নেওয়া যাক ফাইল / জন / পল / জর্জে / রিঙ্গো / বিটলগুলি বিদ্যমান আছে এবং যে ফাইলটির জন্য আপনি অনুসন্ধান করছেন সেটি 'পাথর' বলে

find / stones

'বিটলস' কে 'পাথর' এর সাথে তুলনা করবে এবং যখন 'গুলি' এবং 'বি' মিলবে না তখন তা ফেলে দেবে find

find / | grep stones

এক্ষেত্রে সন্ধান করুন '/ জন / পল / জর্জে / রিঙ্গো / বিটলস' কে গ্রেপ এবং গ্রেপকে কোনও ম্যাচ কিনা তা নির্ধারণের আগে পুরো পথটি দিয়ে তার কাজ করতে হবে।

গ্রেপ তাই আরও বেশি কাজ করছে যার কারণে এটি বেশি সময় নেয়


1
আপনি কি চেষ্টা করে দেখেছেন?
হাউক লেগেছে

3
স্ট্রিং তুলনা (অত্যন্ত সহজ এবং সস্তা) এর ব্যয়টি ডিরেক্টর লুপআপের আইও (বা কেবল ক্যাশেড হলে সিস্কেল) সম্পূর্ণভাবে বামন করে।
মাদুর

গ্রেপ কোনও স্ট্রিং তুলনা নয়, এর নিয়মিত অভিব্যক্তি তুলনা যার অর্থ এটি কোনও ম্যাচ না পাওয়া বা শেষ পর্যন্ত না পৌঁছানো পর্যন্ত পুরো স্ট্রিংয়ের মধ্য দিয়ে তার কাজ করতে হবে। ডিরেক্টরি দেখার জন্য যা কিছু থাকুক না কেন একই রকম।
প্যারানয়েড

@Paranoid হুঁ, কি সংস্করণ খোঁজ বলছ? দৃশ্যত এটি ডেবিয়ানে আমি যে অভ্যস্ত তা খুঁজে পাওয়ার মতো কিছুই নয় ।
পাইপ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.