রিকার্সিভ গ্রেপ বনাম সন্ধান করুন / -প্রকার-এফ-এক্সেক গ্রেপ {} \; কোনটি আরও দক্ষ / দ্রুত?


70

একটি সম্পূর্ণ ফাইল সিস্টেমের কোন ফাইলগুলিতে একটি স্ট্রিং রয়েছে তা সন্ধানের জন্য কোনটি দক্ষ: পুনরাবৃত্তিযোগ্য গ্রেপ বা একটি এক্সিকিউট স্টেটমেন্টে গ্রেপ সহ সন্ধান করুন? আমি ধরেছি আরও কার্যকর হবে কারণ আপনি যদি ফাইল এক্সটেনশন বা ফাইলের নামের সাথে মেলে এমন একটি রেজেক্স জানেন তবে আপনি কমপক্ষে কিছু ফিল্টারিং করতে পারবেন তবে আপনি কেবল যখন জানবেন -type fকোনটি ভাল? জিএনইউ গ্রেপ 2.6.3; সন্ধান করুন (জিএনইউ অনুসন্ধানসমূহ) ৪.৪.২

উদাহরণ:

grep -r -i 'the brown dog' /

find / -type f -exec grep -i 'the brown dog' {} \;


1
গণিত / কম্পিউটার বিজ্ঞান / অ্যালগরিদম দক্ষতা ins't মতামত ভিত্তিক।
গ্রেগ লেভেন্টাল

এটি পরীক্ষা করুন। পুনরাবৃত্তি না হওয়া সত্ত্বেও, এটি এমন একটি বোঝাপড়া দেবে যা আরও ভাল। unix.stackexchange.com/questions/47983/…
রমেশ

8
@ অবিনাশরাজ তিনি মতামত চাইছেন না। তিনি জিজ্ঞাসা করছেন কোনটি আরও দক্ষ এবং / বা দ্রুত , কোনটি "ভাল" নয়। এটি একটি পুরোপুরি উত্তরযোগ্য প্রশ্ন যা এর একটি একক, নির্দিষ্ট উত্তর রয়েছে যা এই দুটি প্রোগ্রাম তাদের কাজটি করে এবং আপনি তাদের অনুসন্ধানের জন্য ঠিক কী দেন তার উপর নির্ভর করে।
টেরডন

2
নোট করুন যে -exec {} +ফর্মটি কাঁটাচামচ কম করবে, তাই তার চেয়ে দ্রুত হওয়া উচিত -exec {} \;। ঠিক সমতুল্য আউটপুট পেতে আপনাকে বিকল্পগুলিতে -H(বা -h) যুক্ত করতে হতে পারে grep
মাইকেল

আপনি সম্ভবত দ্বিতীয়টির জন্য -rবিকল্পটি চান নিgrep
কিওয়ার্টজগুয়ে

উত্তর:


85

আমি নিশ্চিত নই:

grep -r -i 'the brown dog' /*

সত্যিই আপনি বোঝাতে চেয়েছিলেন এর অর্থ হ'ল সমস্ত অ গোপনীয় ফাইল এবং ডায়ারগুলিতে পুনরাবৃত্তির সাথে গ্রেপ হওয়া উচিত /(তবে তারপরেও লুকানো ফাইল এবং ডায়ারের ভিতরে তাকান)।

ধরে নিচ্ছেন আপনার অর্থ:

grep -r -i 'the brown dog' /

কয়েকটি বিষয় লক্ষণীয়:

  • সমস্ত grepবাস্তবায়ন সমর্থন করে না -r। এবং যাগুলির মধ্যে, আচরণগুলির মধ্যে পার্থক্য রয়েছে: কেউ কেউ ডিরেক্টরি ট্রিতে যাওয়ার সময় ডিরেক্টরিগুলির প্রতিলিঙ্কগুলি অনুসরণ করেন (যার অর্থ আপনি একই ফাইলটিতে বেশ কয়েকবার সন্ধান করতে পারেন বা এমনকি অসীম লুপগুলিতে চালাতে পারেন), কিছু না will কিছু ডিভাইস ফাইলের ভিতরে দেখতে পাবেন (এবং এটি /dev/zeroউদাহরণস্বরূপ বেশ কিছুটা সময় নেবে ) বা পাইপ বা বাইনারি ফাইলগুলি ..., কিছু না not
  • grepফাইলগুলি আবিষ্কার করার সাথে সাথে এটি ভিতরে সন্ধান করা শুরু করার সাথে সাথে এটি দক্ষ । তবে এটি কোনও ফাইলে সন্ধান করার সময়, অনুসন্ধানের জন্য এটি আর বেশি ফাইলের সন্ধান করে না (যা সম্ভবত বেশিরভাগ ক্ষেত্রে ঠিক একইভাবে হয়)

তোমার:

find / -type f -exec grep -i 'the brown dog' {} \;

( -rযা এখানে বোঝা যায়নি এটি মুছে ফেলা হয়েছে) মারাত্মকভাবে অক্ষম কারণ আপনি grepপ্রতি ফাইলের মধ্যে একটি চালাচ্ছেন । ;কেবলমাত্র একটি যুক্তি গ্রহণকারী কমান্ডগুলির জন্য ব্যবহার করা উচিত। grepতবুও এখানে, কারণ কেবল একটি ফাইলে দেখায়, এটি ফাইলটির নাম মুদ্রণ করবে না, তাই ম্যাচগুলি কোথায় তা আপনি জানতে পারবেন না।

আপনি ডিভাইস ফাইল, পাইপ, সিমলিংকের ভিতরে খুঁজছেন না ..., আপনি সিমলিংকগুলি অনুসরণ করছেন না, তবে আপনি এখনও সম্ভাব্যভাবে পছন্দ মতো জিনিসগুলি সন্ধান করছেন /proc/mem

find / -type f -exec grep -i 'the brown dog' {} +

অনেক ভাল হবে কারণ grepযতটা সম্ভব কমান্ড চালানো হবে। শেষ রানটিতে কেবল একটি ফাইল না থাকলে আপনি ফাইলটির নাম পাবেন। তার জন্য এটি ব্যবহার করা ভাল:

find / -type f -exec grep -i 'the brown dog' /dev/null {} +

বা জিএনইউ সহ grep:

find / -type f -exec grep -Hi 'the brown dog' {} +

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

জিএনইউ সরঞ্জাম সহ:

find / -type f -print0 | xargs -r0 grep -Hi 'the brown dog'

উপরে হিসাবে, যতটা grepসম্ভব উদাহরণস্বরূপ চালানো হবে, তবে findপ্রথম grepপ্রার্থনা প্রথম ব্যাচের ভিতরে থাকা অবস্থায় আরও ফাইল অনুসন্ধান করা চালিয়ে যাবে । যদিও এটি একটি সুবিধা হতে পারে বা নাও পারে। উদাহরণস্বরূপ, আবর্তনশীল হার্ড ড্রাইভ সঞ্চিত ডেটা সঙ্গে findএবং grepডিস্কে বিভিন্ন অবস্থানগুলি এ সঞ্চিত অ্যাক্সেস ডেটা প্রতিনিয়ত সরাতে ডিস্ক মাথা ঘটাচ্ছে দ্বারা ডিস্ক থ্রুপুট মন্থর করে দেবে। একটি RAID সেটআপে (যেখানে findএবং grepবিভিন্ন ডিস্ক অ্যাক্সেস করতে পারে) বা এসএসডিগুলিতে, এটি একটি ইতিবাচক পার্থক্য করতে পারে।

একটি RAID সেটআপে, বেশ কয়েকটি সমবর্তী grep আমন্ত্রণ চালানো জিনিসগুলির উন্নতিও করতে পারে। এখনও 3 টি ডিস্ক সহ RAID1 স্টোরেজে জিএনইউ সরঞ্জাম সহ,

find / -type f -print0 | xargs -r0 -P2 grep -Hi 'the brown dog'

পারফরম্যান্স উল্লেখযোগ্যভাবে বৃদ্ধি করতে পারে। তবে খেয়াল করুন যে দ্বিতীয় কমান্ডটি grepপূরণ করার জন্য পর্যাপ্ত ফাইলগুলি পাওয়া গেলেই কেবল দ্বিতীয়টি শুরু করা হবে grep। তাড়াতাড়ি -nহওয়ার xargsজন্য আপনি একটি বিকল্প যুক্ত করতে পারেন (এবং প্রার্থনার জন্য কম ফাইলগুলি পাস করুন grep)।

এছাড়াও মনে রাখবেন যে আপনি যদি xargsটার্মিনাল ডিভাইস ব্যতীত আউটপুটটিকে অন্য কোনও দিকে পুনঃনির্দেশ করে থাকেন তবে grepsএসগুলি তাদের আউটপুটটি বাফার শুরু করবে যার অর্থ এই greps গুলিটির আউটপুট সম্ভবত ভুলভাবে ইন্টারলিভড হবে। আপনার stdbuf -oLচারপাশে কাজ করার জন্য তাদের (যেখানে জিএনইউ বা ফ্রিবিএসডি-র মতো উপলব্ধ) ব্যবহার করতে হবে (আপনার এখনও খুব দীর্ঘ লাইন (সাধারণত> 4KiB) নিয়ে সমস্যা হতে পারে) বা প্রত্যেকে একটি আলাদা ফাইলে তাদের আউটপুট লিখতে এবং তাদের সাথে একমত করতে পারেন সব শেষে।

এখানে, আপনি যে স্ট্রিংটির সন্ধান করছেন তা স্থির হয়েছে (একটি রেজিপ্সপ নয়) সুতরাং -Fবিকল্পটি ব্যবহার করে কোনও পার্থক্য হতে পারে ( grepবাস্তবায়নের ফলে ইতিমধ্যে কীভাবে এটি অপ্টিমাইজ করতে হয় তা অসম্ভব )।

আরেকটি জিনিস যা একটি বড় পার্থক্য করতে পারে তা হ'ল আপনি যদি কোনও বহু-বাইট লোকালে থাকেন তবে সিটিতে লোকাল ঠিক করা:

find / -type f -print0 | LC_ALL=C xargs -r0 -P2 grep -Hi 'the brown dog'

ভিতরে অনুসন্ধান এড়াতে /proc, /sys..., -xdevআপনি অনুসন্ধান করতে চান ফাইল সিস্টেমটি ব্যবহার করুন এবং নির্দিষ্ট করুন:

LC_ALL=C find / /home -xdev -type f -exec grep -i 'the brown dog' /dev/null {} +

বা আপনি যে পথগুলি স্পষ্টভাবে বাদ দিতে চান তা ছাঁটাই করুন:

LC_ALL=C find / \( -path /dev -o -path /proc -o -path /sys \) -prune -o \
  -type f -exec grep -i 'the brown dog' /dev/null {} +

আমি মনে করি না যে কেউ আমাকে কোনও সংস্থানে নির্দেশ করতে পারে - বা ব্যাখ্যা - কী।। এবং + এর অর্থ mean এক্সিকিউট, গ্রেপ বা আমি যে সোলারিস বক্সটি ব্যবহার করছি তার জন্য ম্যান পৃষ্ঠাগুলিতে আমি দেখতে পাচ্ছি না। শেল কি কেবল ফাইলের নামগুলি যুক্ত করে গ্রেপ-এ পাঠিয়ে দিচ্ছে?


অই হ্যাঁ. ম্যান পৃষ্ঠার মধ্যে অনুসন্ধান করা অবস্থায় আমি আমার {চর থেকে পালাচ্ছিলাম না। আপনার লিঙ্কটি আরও ভাল; আমি মানুষ পৃষ্ঠা পড়তে ভয়ানক মনে।

1
RAID1 ডাব্লু / 3 ডিস্ক? কী বিজোড় ...
টিঙ্ক

1
@ টিঙ্ক, হ্যাঁ RAID1 2 বা তার বেশি ডিস্কে রয়েছে। 2 টি ডিস্কের তুলনায় 3 টি ডিস্কের সাহায্যে আপনি রিডানডেনসি বাড়াতে পারেন এবং লেখার পারফরম্যান্সটি প্রায় একই রকম হয়। 2 টির বিপরীতে 3 টি ডিস্কের সাহায্যে এর অর্থ আপনিও ত্রুটিগুলি সংশোধন করতে পারবেন, যখন কোনও একটি অনুলিপিতে কিছুটা উল্টে যায় আপনি 2 টি ডিস্কের সাথে সমস্ত 3 অনুলিপি পরীক্ষা করে কোনটি ঠিক তা বলতে পারবেন, আপনি পারবেন না সত্যিই বলুন।
স্টাফেন চেজেলাস

13

তাহলে *grepকল আপনার কাছে গুরুত্বপূর্ণ নয় তারপর প্রথম মাত্র এক উদাহরণ হিসেবে বলা যায় যেমন আরও দক্ষ হওয়া উচিত grepশুরু হয়, এবং কাটাচামচ মুক্ত নয়। বেশিরভাগ ক্ষেত্রে এটি তীব্র হলেও তীব্র হবে *তবে প্রান্তের ক্ষেত্রে বাছাইটি তার বিপরীত হতে পারে।

অন্যান্য find- grepকাঠামো থাকতে পারে যা বিশেষত অনেক ছোট ফাইলের সাথে আরও ভাল কাজ করে। একবারে বড় পরিমাণে ফাইল এন্ট্রি এবং আইনোডগুলি পড়া ঘোরানো মিডিয়াতে পারফরম্যান্সের উন্নতি দিতে পারে।

তবে আসুন সিস্কল পরিসংখ্যানগুলিতে এক নজর দেওয়া যাক:

আবিষ্কার

> strace -cf find . -type f -exec grep -i -r 'the brown dog' {} \;
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
 97.86    0.883000        3619       244           wait4
  0.53    0.004809           1      9318      4658 open
  0.46    0.004165           1      6875           mmap
  0.28    0.002555           3       977       732 execve
  0.19    0.001677           2       980       735 stat
  0.15    0.001366           1      1966           mprotect
  0.09    0.000837           0      1820           read
  0.09    0.000784           0      5647           close
  0.07    0.000604           0      5215           fstat
  0.06    0.000537           1       493           munmap
  0.05    0.000465           2       244           clone
  0.04    0.000356           1       245       245 access
  0.03    0.000287           2       134           newfstatat
  0.03    0.000235           1       312           openat
  0.02    0.000193           0       743           brk
  0.01    0.000082           0       245           arch_prctl
  0.01    0.000050           0       134           getdents
  0.00    0.000045           0       245           futex
  0.00    0.000041           0       491           rt_sigaction
  0.00    0.000041           0       246           getrlimit
  0.00    0.000040           0       489       244 ioctl
  0.00    0.000038           0       591           fcntl
  0.00    0.000028           0       204       188 lseek
  0.00    0.000024           0       489           set_robust_list
  0.00    0.000013           0       245           rt_sigprocmask
  0.00    0.000012           0       245           set_tid_address
  0.00    0.000000           0         1           uname
  0.00    0.000000           0       245           fchdir
  0.00    0.000000           0         2         1 statfs
------ ----------- ----------- --------- --------- ----------------
100.00    0.902284                 39085      6803 total

গ্রেপ শুধুমাত্র

> strace -cf grep -r -i 'the brown dog' .
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
 40.00    0.000304           2       134           getdents
 31.71    0.000241           0       533           read
 18.82    0.000143           0       319         6 openat
  4.08    0.000031           4         8           mprotect
  3.29    0.000025           0       199       193 lseek
  2.11    0.000016           0       401           close
  0.00    0.000000           0        38        19 open
  0.00    0.000000           0         6         3 stat
  0.00    0.000000           0       333           fstat
  0.00    0.000000           0        32           mmap
  0.00    0.000000           0         4           munmap
  0.00    0.000000           0         6           brk
  0.00    0.000000           0         2           rt_sigaction
  0.00    0.000000           0         1           rt_sigprocmask
  0.00    0.000000           0       245       244 ioctl
  0.00    0.000000           0         1         1 access
  0.00    0.000000           0         1           execve
  0.00    0.000000           0       471           fcntl
  0.00    0.000000           0         1           getrlimit
  0.00    0.000000           0         1           arch_prctl
  0.00    0.000000           0         1           futex
  0.00    0.000000           0         1           set_tid_address
  0.00    0.000000           0       132           newfstatat
  0.00    0.000000           0         1           set_robust_list
------ ----------- ----------- --------- --------- ----------------
100.00    0.000760                  2871       466 total

1
একটি সম্পূর্ণ ফাইল সিস্টেম অনুসন্ধানের স্কেলে, কাঁটাচামচ নগণ্য। আই / ও হ'ল আপনি হ্রাস করতে চান।
গিলস

যদিও এটি ওপি থেকে একটি ত্রুটি, তুলনাটি ভুল, আপনার ব্যবহারের সময় -rপতাকাটি সরিয়ে নেওয়া উচিত । আপনি দেখতে পাচ্ছেন যে ঘটনার সংখ্যার সাথে তুলনা করে এটি একই ফাইলগুলি বারবার অনুসন্ধান করেছিল । grepfindopen
কিওয়ার্টজগুয়ে

1
@ কিওয়ার্টজগুয়ে, না, গ্যারান্টি থাকা -rউচিত কারণ যেহেতু -type fগ্যারান্টির কোনও তর্কই ডিরেক্টরি নয়। একাধিক open()গুলি grepপ্রতিটি আহ্বানে (গ্রন্থাগারগুলি, স্থানীয়করণের ডেটা ...) খোলার অন্যান্য ফাইলগুলির চেয়ে বেশি সম্ভাবনা রয়েছে (আমার উত্তর বিটিডব্লিউতে সম্পাদনার জন্য ধন্যবাদ)
স্টাফেন চ্যাজেলাস

5

যদি আপনি কোনও এসএসডি তে থাকেন এবং সময় সন্ধানের বিষয়টি অবহেলিত হয় তবে আপনি জিএনইউ সমান্তরাল ব্যবহার করতে পারেন:

find /path -type f | parallel --gnu --workdir "$PWD" -j 8 '
    grep -i -r 'the brown dog' {} 
'

এটি যা findখুঁজে পেয়েছে তার ভিত্তিতে একই সময়ে 8 টি গ্রেপ প্রক্রিয়া চালিত করবে ।

এটি একটি হার্ড ডিস্ক ড্রাইভ ছিন্ন করতে পারে, তবে একটি এসএসডি এর সাথে এটি বেশ ভালভাবে মোকাবেলা করা উচিত।


-1

এই সম্পর্কে আরও একটি বিষয় বিবেচনা করার বিষয় হল নীচে।

ডিরেক্টরি যে কোন করবেন grep যাও recursively যেতে মাধ্যমে আপনার সিস্টেমের চেয়ে বেশি ফাইল থাকতে হবে nofile সেটিং? (উদাহরণস্বরূপ, ওপেন ফাইল হ্যান্ডলগুলির সংখ্যা, বেশিরভাগ লিনাক্স ডিস্ট্রোজে ডিফল্ট 1024 হয়)

যদি তাই হয়, তারপর এটি হ 'ল যেতে যেহেতু এর নির্দিষ্ট কিছু সংস্করণে উপায় , grep একটি সঙ্গে বোমা হবে অত্যন্ত দীর্ঘ আর্গুমেন্ট তালিকার ত্রুটি যখন এটি একাধিক ফাইল চেয়ে সর্বোচ্চ খোলা ফাইল সেটিং হ্যান্ডলগুলি সঙ্গে একটি ডিরেক্টরি হিট।

শুধু আমার 2 ¢


1
grepবোমা ফাটাবে কেন ? কমপক্ষে জিএনইউ গ্রেপ সহ যদি আপনি অনুসরণের সাথে কোনও পথ দেন /এবং ব্যবহার করেন তবে -Rএটি কেবল ডিরেক্টরিগুলির মাধ্যমে পুনরাবৃত্তি হয়। শেল কিছু প্রসারিত করতে, যদি না আপনি শেল-globs দিতে যাচ্ছে না। সুতরাং প্রদত্ত উদাহরণে ( /*) কেবল /পদার্থের বিষয়বস্তু নয়, যে সাবফোল্ডারগুলি কেবল সহজেই গণনা করা হবে grep, শেল থেকে আর্গুমেন্ট হিসাবে পাস হবে না।
0xC0000022L

ঠিক আছে, ওপি বিবেচনা করে পুনরাবৃত্তভাবে অনুসন্ধানের বিষয়ে জিজ্ঞাসা করছিল (উদাঃ "গ্রেপ-আর-আই 'বাদামী কুকুর' / *"), আমি জিএনইউ এর গ্রেপ (কমপক্ষে সংস্করণ ২.৯) এর সাথে বোমা ফেলা দেখেছি : "- বাশ: / বিন / গ্রেপ: আর্গুমেন্টের তালিকা খুব দীর্ঘ "যে ডিরেক্টরিটিতে 14,000 টিরও বেশি সাব-ডিরেক্টরি রয়েছে সেগুলিতে ওপি ব্যবহৃত সঠিক অনুসন্ধান ব্যবহার করে using
বি.কাটজ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.