একাধিক এবং নিদর্শন দিয়ে কিভাবে গ্রেপ চালানো যায়?


86

আমি নিখুঁত নিদর্শনগুলির মধ্যে একাধিক প্যাটার্ন মিলটি পেতে চাই , অর্থাত্ একটি ক্রমটিতে বেশ কয়েকটি গ্রেপ চালানোর সমতুল্য:

grep pattern1 | grep pattern2 | ...

সুতরাং কিভাবে এটি কিছু রূপান্তর করতে?

grep pattern1 & pattern2 & pattern3

আমি একক গ্রেপ ব্যবহার করতে চাই কারণ আমি গতিশীলভাবে তর্কগুলি তৈরি করছি, তাই সবকিছুকে একটি স্ট্রিংয়ে ফিট করতে হবে। ফিল্টার ব্যবহার করা সিস্টেম বৈশিষ্ট্য, গ্রেপ নয়, সুতরাং এটি এটির পক্ষে যুক্তি নয়।


এই প্রশ্নটির সাথে গুলিয়ে ফেলবেন না:

grep "pattern1\|pattern2\|..."

এটি একটি ওআর মাল্টি প্যাটার্ন মিল।



উত্তর:


78

agrep এই সিনট্যাক্স দিয়ে এটি করতে পারেন:

agrep 'pattern1;pattern2'

জিএনইউ দিয়ে grep, যখন পিসিআরই সমর্থন দিয়ে নির্মিত হয়, আপনি এটি করতে পারেন:

grep -P '^(?=.*pattern1)(?=.*pattern2)'

সঙ্গে ASTgrep :

grep -X '.*pattern1.*&.*pattern2.*'

(যোগ .*s হিসেবে <x>&<y>স্ট্রিং উভয় মেলে মিলে যায় <x>এবং <y> ঠিক , a&bসেখানে এমন কোন স্ট্রিং, যাতে পারে যেমন মেলে না হবে হতে উভয় aএবং bএকই সময়ে)।

যদি নিদর্শনগুলি ওভারল্যাপ না হয় তবে আপনি এটি করতে সক্ষমও হতে পারেন:

grep -e 'pattern1.*pattern2' -e 'pattern2.*pattern1'

awkইতিমধ্যে উল্লিখিত হিসাবে সম্ভবত বহনযোগ্য সর্বোত্তম উপায় :

awk '/pattern1/ && /pattern2/'

সাথে sed:

sed -e '/pattern1/!d' -e '/pattern2/!d'

দয়া করে সাবধান থাকুন যে তাদের সকলেরই নিয়মিত প্রকাশের বাক্য গঠন হবে।


1
agrepসিনট্যাক্স আমার জন্য কাজ না করে ... কোন সংস্করণটি এটা চালু ছিল?
রমন

1992 এর আগে রামান 2.04 ইতিমধ্যে এটি পেয়েছিল। আমার বিশ্বাস করার কোনও কারণ নেই যে এটি শুরু থেকেই ছিল না। ঝলক / ওয়েবগ্লিম্পসেরagrep সাথে আরও নতুন (1992 এর পরে) সংস্করণগুলি পাওয়া যায় । সম্ভবত আপনার আলাদা প্রয়োগ রয়েছে। আমি এবং AST-, grep সংস্করণের জন্য ভুল ছিল যদিও, জন্য বিকল্প উদ্দীপ্ত regexps হয় না । -X-A
স্টাফেন চেজেলাস

@ agrepস্টাফেনচাজেলাস ধন্যবাদ, ফেডোরা ২৩ এ আমার ০.৮.০ রয়েছে you এটি agrepআপনার উল্লেখের চেয়ে আলাদা বলে মনে হচ্ছে ।
রমন

1
@Raman, পুলিশের মত শোনাচ্ছে Treagrep
স্টাফেন চেজেলাস

2
@ টেকি, বা ঠিকawk '/p1/ && /p2/ {n++}; END {print 0+n}'
স্টাফেন চেজেলাস

19

আপনি গ্রেপ সংস্করণ নির্দিষ্ট করেন নি, এটি গুরুত্বপূর্ণ। কিছু রিজএক্সপক্স ইঞ্জিন 'এবং' ব্যবহার করে এবং একাধিক ম্যাচ গ্রাফ করার অনুমতি দেয় তবে এটি অ-মানক এবং অ-বহনযোগ্য বৈশিষ্ট্য। তবে, কমপক্ষে জিএনইউ গ্রেপ এটি সমর্থন করে না।

OTOH আপনি কেবল গ্রেড প্রতিস্থাপন করতে পারেন সেড, জাজ, পারল ইত্যাদি দিয়ে (ওজন বৃদ্ধির ক্রমে তালিকাবদ্ধ)। অ্যাজকের সাথে, কমান্ডটি দেখতে হবে

awk '/ regexp1 / && / regexp2 / && / regexp3 / {মুদ্রণ; } '

এবং এটি সহজ উপায়ে কমান্ড লাইনে নির্দিষ্ট করার জন্য নির্মিত যেতে পারে।


3
কেবল মনে রাখবেন যে BRE এর সাধারণ ব্যবহারের বিপরীতে awkযেমন পূর্বের ব্যবহার হয়, যেমন এর সমতুল্য । grep -Egrep
jw013

3
awk'র রেজেক্সেসগুলিকে ইআরই বলা হয়, তবে বাস্তবে তারা কিছুটা মূর্তিপ্রিয়। এখানে যে কারও যত্ন নেওয়ার
dubiousjim

আপনাকে ধন্যবাদ, গ্রেপ ২..3.৩ (ওপেনসুএস)। আমি আপনাকে উত্সাহিত করেছি, তবে আমি প্রশ্নটি কিছু সময়ের জন্য উন্মুক্ত রাখব, সম্ভবত গ্রাপের জন্য কিছু কৌশল আছে (এমন নয় যে আমি অপছন্দ করি না awk- কেবল আরও জানাই ভাল)
গ্রিনল্ডম্যান

2
ডিফল্ট ক্রিয়াটি ম্যাচিং লাইনটি মুদ্রণ করা হয় যাতে { print; }অংশটি এখানে প্রয়োজনীয় বা দরকারী না হয়।
ট্রিপলি

7

যদি patternsপ্রতি লাইনে একটি প্যাটার্ন থাকে তবে আপনি এর মতো কিছু করতে পারেন:

awk 'NR==FNR{a[$0];next}{for(i in a)if($0!~i)next}1' patterns -

বা এটি নিয়মিত প্রকাশের পরিবর্তে সাবস্ট্রিংয়ের সাথে মেলে:

awk 'NR==FNR{a[$0];next}{for(i in a)if(!index($0,i))next}1' patterns -

ক্ষেত্রে যে ইনপুট কোন লাইন এর পরিবর্তে সমস্ত মুদ্রণ করতে patternsখালি, প্রতিস্থাপন NR==FNRসঙ্গে FILENAME==ARGV[1], অথবা ARGIND==1মধ্যে gawk

এই ফাংশনগুলি STDIN এর লাইনগুলি মুদ্রণ করে যা প্রতিটি স্ট্রিংকে একটি স্ট্রিং হিসাবে আর্গুমেন্ট হিসাবে নির্দিষ্ট করে contain gaসকল গ্রেপকে বোঝায় এবং gaiকেস উপেক্ষা করে।

ga(){ awk 'FILENAME==ARGV[1]{a[$0];next}{for(i in a)if(!index($0,i))next}1' <(printf %s\\n "$@") -; }
gai(){ awk 'FILENAME==ARGV[1]{a[tolower($0)];next}{for(i in a)if(!index(tolower($0),i))next}1' <(printf %s\\n "$@") -; }

7

এটি খুব ভাল সমাধান নয় তবে কিছুটা দুর্দান্ত "কৌশল" চিত্রিত করে

function chained-grep {
    local pattern="$1"
    if [[ -z "$pattern" ]]; then
        cat
        return
    fi    

    shift
    grep -- "$pattern" | chained-grep "$@"
}

cat something | chained-grep all patterns must match order but matter dont

1
হয় chained-grep()বা function chained-grepনা ব্যবহার করুন function chained-grep(): unix.stackexchange.com/questions/73750/…
নিসেটামা

3

git grep

বুলিয়ান এক্সপ্রেশন git grepব্যবহার করে একাধিক নিদর্শনগুলির সমন্বয় করে সিনট্যাক্সটি এখানে :

git grep --no-index -e pattern1 --and -e pattern2 --and -e pattern3

উপরের কমান্ডটি একবারে সমস্ত নিদর্শনগুলির সাথে মিলিত লাইনগুলি মুদ্রণ করবে।

--no-index বর্তমান ডিরেক্টরিতে ফাইলগুলি অনুসন্ধান করুন যা গিট দ্বারা পরিচালিত নয়।

man git-grepসাহায্যের জন্য পরীক্ষা করুন ।

আরো দেখুন:

জন্য অথবা অপারেশন, দেখুন:


1

ripgrep

এখানে উদাহরণ ব্যবহার করে rg:

rg -N '(?P<p1>.*pattern1.*)(?P<p2>.*pattern2.*)(?P<p3>.*pattern3.*)' file.txt

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

জিএইচ -875 এ সম্পর্কিত বৈশিষ্ট্য অনুরোধটি দেখুন ।


1

এখানে আমার নেওয়া, এবং এটি একাধিক লাইনে শব্দের জন্য কাজ করে:

যতগুলি find . -type fঅনুসরণ করে
-exec grep -q 'first_word' {} \;
এবং এর সাথে শেষ কীওয়ার্ডটি ব্যবহার করুন
-exec grep -l 'nth_word' {} \;

-q
-lম্যাচগুলি সহ শান্ত / নীরব ফাইলগুলি দেখান

নিম্নলিখিতটিতে নামগুলির মধ্যে 'খরগোশ' এবং 'ছিদ্র' শব্দের সাথে ফাইলের নামের তালিকা রয়েছে:
find . -type f -exec grep -q 'rabbit' {} \; -exec grep -l 'hole' {} \;


-2

শব্দ (বা নিদর্শন) এর সব অনুসন্ধান করতে, আপনাকে করতে লুপ জন্য grep চালানো । এখানে মূল সুবিধাটি হ'ল রেগেক্সের একটি তালিকা থেকে অনুসন্ধান করা ।

আমার উত্তরটি একটি বাস্তব উদাহরণ দিয়ে সম্পাদনা করুন :

# search_all_regex_and_error_if_missing.sh 

find_list="\
^a+$ \
^b+$ \
^h+$ \
^d+$ \
"

for item in $find_list; do
   if grep -E "$item" file_to_search_within.txt 
   then
       echo "$item found in file."
   else
       echo "Error: $item not found in file. Exiting!"
       exit 1
   fi
done

এখন এই ফাইলটিতে এটি চালানো যাক:

খরচ করতেছি আমরা জনগন

aaaaaaa

bbbbbbbbb

ababbabaabbaaa

ccccccc

dsfsdf

bbbb

cccdd

এএ

CAA

# ./search_all_regex_and_error_if_missing.sh

আআআআআআআআআআ

in a + file ফাইলে পাওয়া গেছে।

bbbbbbbbb bbbb

^ b + file ফাইলে পাওয়া গেছে।

খরচ করতেছি আমরা জনগন

^ h + file ফাইলে পাওয়া গেছে।

ত্রুটি: in d + file ফাইলটিতে পাওয়া যায় নি। প্রস্থান করা হচ্ছে!


1
আপনার যুক্তি ত্রুটিযুক্ত - আমি ALLঅপারেটর জন্য জিজ্ঞাসা , আপনার কোড ORঅপারেটর হিসাবে কাজ করে , না AND। এবং বিটিডব্লিউ। ORএটির জন্য ( ) সঠিক প্রশ্নে সঠিক সমাধান দেওয়া।
গ্রীনল্ডম্যান

@ গ্রিনল্ডম্যান যুক্তিটি সহজ: তালিকার সমস্ত শব্দ / নিদর্শনগুলির জন্য উইল লুপ করবে এবং যদি এটি ফাইলটিতে পাওয়া যায় - এটি মুদ্রণ করবে। শব্দটি খুঁজে পাওয়া যায় নি যদি আপনার প্রয়োজনের ব্যবস্থা না নেওয়া হয় তবে অন্যটি সরিয়ে ফেলুন।
নোয়াম মানোস

1
আমি আপনার যুক্তি পাশাপাশি আমার প্রশ্নটিও বুঝতে পারি - আমি ANDঅপারেটর সম্পর্কে জিজ্ঞাসা করছিলাম , অর্থ যদি এটি প্যাটার্ন এ এবং প্যাটার্ন বি এবং প্যাটার্ন সি এর সাথে মেলে তবে ফাইলটি কেবলমাত্র একটি ইতিবাচক হিট ... ANDযদি আপনার ক্ষেত্রে ফাইল মেলে তবে ইতিবাচক হিট প্যাটার্ন এ বা প্যাটার্ন বি বা ... আপনি কি এখন পার্থক্যটি দেখতে পাচ্ছেন?
গ্রিনোল্ডম্যান

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

আপনার চোখের সামনে এটি ঠিক আছে, প্রথম ম্যাচটি কার্যকর হওয়ার ঠিক পরে আপনার ইতিবাচক মিল রয়েছে। আপনার সমস্ত ফলাফল "সংগ্রহ" করা উচিত এবং ANDসেগুলি গণনা করা উচিত। তারপরে আপনার একাধিক ফাইল চালানোর জন্য স্ক্রিপ্টটি পুনর্লিখন করা উচিত - তবে সম্ভবত আপনি বুঝতে পারবেন যে প্রশ্নটি ইতিমধ্যে উত্তর হয়ে গেছে এবং আপনার প্রচেষ্টা টেবিলে কিছুই আনেনি, দুঃখিত।
গ্রীনল্ডম্যান
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.