যেখানে দুটি ভিন্ন শব্দ বিদ্যমান সেখানে ফাইলগুলি কীভাবে অনুসন্ধান করবেন?


14

আমি ফাইলগুলি অনুসন্ধান করার জন্য একটি উপায় খুঁজছি যেখানে একই ফাইলটিতে দুটি শব্দ উদাহরণ রয়েছে। আমি আমার অনুসন্ধানগুলি এখন পর্যন্ত সম্পাদন করতে নিম্নলিখিতটি ব্যবহার করছি:

find . -exec grep -l "FIND ME" {} \;

আমি যে সমস্যাটি চালাচ্ছি তা হ'ল যদি "FIND" এবং "ME" এর মধ্যে ঠিক একটি স্থান না থাকে, সন্ধানের ফলাফলটি ফাইলটি দেয় না। আমি কীভাবে প্রাক্তন অনুসন্ধান স্ট্রিংটিকে অভিযোজিত করব যেখানে "FIND" এবং "ME" উভয় শব্দ "ফাইন্ড এমই" এর বিপরীতে কোনও ফাইলে বিদ্যমান?

আমি এআইএক্স ব্যবহার করছি।


1
শব্দগুলি ফাইলের কোথাও বিদ্যমান আছে, বা সেগুলি সবসময় একই লাইনে থাকে?
সোব্রিক

উদ্দেশ্য একই লাইন ছিল।
চাদ হ্যারিসন

একটি বিকল্প, যদি শব্দের একই লাইনে সঙ্গে একটি রেগুলার এক্সপ্রেশন ব্যবহার করা grep -E/ egrepযে সমস্ত নিদর্শন আপনি আগ্রহী এবং যা বর্ণনা (ব্যবহার +পরিবর্তে ;যদি আপনার খোঁজ জন্য সমর্থন আছে +
MattBianco

উত্তর:


21

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

find . -type f  -exec grep -lZ FIND {} + | xargs -r0 grep -l ME

আপনি মানকভাবে করতে পারেন:

find . -type f -exec grep -q FIND {} \; -exec grep -l ME {} \;

কিন্তু এটি ফাইলের জন্য দুটি গ্রেপ চালাবে। এতগুলি চালনা এড়াতে grepএবং এখনও ফাইলের নামগুলিতে কোনও অক্ষরকে অনুমতি দেওয়ার সময় পোর্টেবল হতে পারে, আপনি এটি করতে পারেন:

convert_to_xargs() {
  sed "s/[[:blank:]\"\']/\\\\&/g" | awk '
    {
      if (NR > 1) {
        printf "%s", line
        if (!index($0, "//")) printf "\\"
        print ""
      }
      line = $0
    }'
    END { print line }'
}

find .//. -type f |
  convert_to_xargs |
  xargs grep -l FIND |
  convert_to_xargs |
  xargs grep -l ME

findএক্সারগের জন্য উপযুক্ত আউটপুটটিকে রূপান্তর করার ধারণাটি (যেটি ফাঁকা (এসপিসি / টিএবি / এনএল এবং আপনার স্থানীয় স্থানের কিছু ফাঁকা কিছু বাস্তবায়নের সাথে প্রত্যাশা করে xargs)) শব্দের পৃথকীকরণের তালিকা যেখানে একক, ডাবল উদ্ধৃতি এবং ব্যাকস্ল্যাশ করতে পারে ফাঁকা ফাঁকা এবং একে অপরের)।

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

./a
./b

আমরা কোন ভাবেই জানেন যে এটা একটি ফাইল নামক কিনা পেয়েছেন bএকটি ডিরেক্টরি নামক a<NL>.অথবা যদি এটিকে দুটি ফাইল aএবং b

ব্যবহার করে .//., কারণ //অন্যথায় কোনও ফাইলে পাথ আউটপুট হিসাবে উপস্থিত হতে পারে না find(কারণ খালি নামের কোনও ডিরেক্টরি হিসাবে আর /কোনও ফাইলের নামে অনুমোদিত নয়), আমরা জানি যে আমরা যদি এমন একটি লাইন দেখি যা //তখন থাকে নতুন ফাইলনামের প্রথম লাইন। সুতরাং আমরা এই awkকমান্ডটি সমস্ত নতুন লাইন অক্ষর থেকে বাঁচার জন্য ব্যবহার করতে পারি তবে সেই লাইনগুলির আগে যেগুলি রয়েছে।

যদি আমরা উপরের উদাহরণটি নিই findতবে প্রথম ক্ষেত্রে (একটি ফাইল) আউটপুট আসবে:

.//a
./b

কোনটি অবতরণ করে:

.//a\
./b

সুতরাং xargsএটি একটি যুক্তি হিসাবে দেখায়। এবং দ্বিতীয় ক্ষেত্রে (দুটি ফাইল):

.//a
.//b

যা awkযেমনটি ছেড়ে যায়, তাই xargsদুটি যুক্তি দেখায়।


কেন find ... -print0এবং grep --nullপরিবর্তে ব্যবহার করবেন না?
রাজ্জিত

@ রেজ্জিত, নিশ্চিত আপনি নিশ্চিত কি না। grep --null(ওরফে-জেড) প্রথমটিতে ব্যবহৃত হয় তবে এটি জিএনইউ এক্সটেনশন। -print0(অন্য একটি জিএনইউ এক্সটেনশন) এখানে সহায়তা করবে না।
স্টাফেন চেজেলাস

ধন্যবাদ। আমি আপনার শেল কোডটি কোনও স্ক্রিপ্টে মোড়াতে চাই যা অনুসন্ধান ডিরেক্টরিটি কমান্ড লাইন থেকে একটি যুক্তি হিসাবে গ্রহণ করবে। আমি .//.এখনও নিশ্চিত হওয়ার অর্থটি খুব নিশ্চিত নই এবং ভাবছি যে কমান্ড লাইন থেকে কোনও যুক্তি গ্রহণ করার জন্য আমি কীভাবে এটি সংশোধন করতে পারি $1?
টিম

ধন্যবাদ। আপনার আদেশে, এর -print0সাথে findএবং -0সাথে ব্যবহার করা কি প্রয়োজনীয় xargs?
টিম

@ টিম, আপনার অর্থ কী তা নিশ্চিত নন। আমি find -print0আমার উত্তরে কোথাও ব্যবহার করি না ।
স্টাফেন চেজেলাস

8

ফাইল একটি একক ডিরেক্টরির মধ্যে এবং তাদের নাম স্থান, ট্যাব, NEWLINE রয়েছে না থাকে তাহলে *, ?কিংবা [অক্ষর এবং দিয়ে শুরু করবেন না -কিংবা ., এই আমাকে ধারণকারী ফাইলের একটি তালিকা পাবে, তারপর বেশী যে আকার কমিয়ে আনতে যে এছাড়াও FIND রয়েছে।

grep -l FIND `grep -l ME *`

এই আরও upvotes প্রয়োজন !! "গৃহীত" উত্তরের চেয়ে অনেক বেশি মার্জিত। আমার জন্য কাজ করেছেন।
রোব্লগিক

দু'টি grep -l CategoryLinearAxis `grep -l labelJsFunction *`বৈশিষ্ট্যযুক্ত ফাইলগুলির সন্ধানের জন্য কেবল এটি করেছিলেন। এটি করার এক নিখুঁত উপায়। +1
WEBjuju

3

awkআপনি চালাতে পারে সাথে :

find . -type f  -exec awk 'BEGIN{cx=0; cy=0}; /FIND/{cx++}
/ME/{cy++}; END{if (cx > 0 && cy > 0) print FILENAME}' {} \;

এটি যথাযথভাবে মিলিত লাইনের জন্য cxএবং cyএটি গণনা FINDকরে ME। ইন ENDব্লক, উভয় কাউন্টারে> 0, তাহলে এটি ছাপে FILENAME
এটি এর সাথে আরও দ্রুত / আরও দক্ষ হবে gnu awk:

find . -type f  -exec gawk 'BEGINFILE{cx=0; cy=0}; /FIND/{cx++}
/ME/{cy++}; ENDFILE{if (cx > 0 && cy > 0) print FILENAME}' {} +

2

অথবা এটি ব্যবহার করুন egrep -eবা grep -Eপছন্দ করুন:

find . -type f -exec egrep -le '(ME.*FIND|FIND.*ME)' {} \;

অথবা

find . -type f -exec grep -lE '(ME.*FIND|FIND.*ME)' {} +

সম্পাদনা করা +কমান্ডটিতে যুক্তি হিসাবে একাধিক ফাইল (পথ) নাম যুক্ত করে (যদি সমর্থিত হয়) সন্ধান করে -exec। এটি প্রক্রিয়াগুলি সংরক্ষণ করে এবং তার চেয়ে অনেক দ্রুততর \;যা প্রতিটি ফাইলের জন্য একবার কমান্ডের অনুরোধ জানায়।

-type f ডিরেক্টরিতে গ্রেপিং এড়ানোর জন্য কেবলমাত্র ফাইলের সাথে মেলে।

'(ME.*FIND|FIND.*ME)'"FEND" বা "ME" এর পরে "FIND" এর পরে "ME" ধারণকারী যে কোনও লাইনের সাথে মিলে যাওয়া একটি নিয়মিত প্রকাশ expression (শেলটি বিশেষ অক্ষরের ব্যাখ্যা থেকে বিরত রাখতে একক উদ্ধৃতি)।

একটি যোগ করুন -iথেকে grepকমান্ড এটা কেস-অবশ করা।

কেবলমাত্র "MI" এর আগে "FIND" আসে এমন লাইনগুলি মেলে, ব্যবহার করুন 'FIND.*ME'

শব্দের মধ্যে শূন্যস্থান প্রয়োজন (1 বা আরও বেশি, তবে কিছুই নয়): 'FIND +ME'

শব্দের মধ্যে স্পেস (0 বা আরও বেশি কিছু, তবে কিছুই নয়) অনুমতি দেওয়ার জন্য: 'FIND *ME'

সংমিশ্রণগুলি নিয়মিত এক্সপ্রেশন সহ অন্তহীন এবং আপনি কেবলমাত্র সারি-সময়ে-সময়ে ভিত্তিতে মেলাতে আগ্রহী হন, যেমন এনড্রেপ খুব শক্তিশালী।


বেশিরভাগ গ্রেপস কি "-r" সমর্থন করে না? এটি "সন্ধান" মুছে ফেলবে, তবে গাছটিতে সকেট বা অন্যান্য অপ-প্লেইন ফাইল থাকতে পারে।
চোরের মুহুর্ত

ওপি এআইএক্স ব্যবহার করে এবং findপ্রশ্নটিতে ছিল।
ম্যাটবিয়ানকো

0

গৃহীত উত্তরটির দিকে তাকানো, এটি হওয়া দরকারের চেয়ে জটিল বলে মনে হচ্ছে। এর গনুহ সংস্করণ findএবং grepএবং xargsসমর্থন শূন্য-সমাপ্ত স্ট্রিং। এটি এতটা সহজ:

find . -type f -print0 | xargs -0 grep -l --null FIND | xargs -0 grep -l ME

findআপনার ইচ্ছার ফাইলগুলিতে ফিল্টার করার জন্য আপনি আপনার আদেশটি পরিবর্তন করতে পারেন এবং এটি কোনও অক্ষরযুক্ত ফাইলের সাথে কাজ করে; sedপার্সিংয়ের যুক্ত জটিলতা ছাড়াই । আপনি যদি ফাইলগুলি আরও প্রক্রিয়া --nullকরতে চান তবে সর্বশেষে আরও একটি যুক্ত করুনgrep

find . -type f -print0 | xargs -0 grep -l --null FIND | xargs -0 grep -l --null ME | xargs -0 echo

এবং, একটি ফাংশন হিসাবে:

find_strings() {
    find . -type f -print0 | xargs -0 grep -l --null "$1" | xargs -0 grep -l "$2"
}

স্পষ্টতই, আপনি যদি এই সরঞ্জামগুলির GNU সংস্করণ না চালাচ্ছেন তবে গ্রহণযোগ্য উত্তরটি ব্যবহার করুন।


1
--null, --print0, -0সব গনুহ এক্সটেনশানগুলি আছে। যদিও তাদের মধ্যে কিছু আজকাল অন্য বাস্তবায়নে পাওয়া যায়, তারা এখনও বহনযোগ্য নয় এবং পসিক্স বা ইউনিক্স স্ট্যান্ডার্ডে নেই।
স্টাফেন চেজেলাস
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.