পাইপের চরিত্রের ধরণ সহ আমি কীভাবে একাধিক নিদর্শনগুলির জন্য গ্রেপ করব?


623

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

grep (foo|bar) *.txt

তবে শেলটি |পাইপ হিসাবে ব্যাখ্যা করে এবং যখন কার্যকর barহয় না তখন অভিযোগ করে ।

একই সেট ফাইলগুলিতে আমি কীভাবে একাধিক নিদর্শনগুলির জন্য গ্রেপ করতে পারি?



গ্রেপ 'শব্দ 1 \ | শব্দ 2 \ | শব্দ 3' / পথ / থেকে / ফাইল
লাম্বোদার

উত্তর:


861

প্রথমত, আপনাকে শেল দ্বারা বিস্তৃতি থেকে প্যাটার্নটি রক্ষা করতে হবে। এটি করার সবচেয়ে সহজ উপায় হল এর চারপাশে একক উদ্ধৃতি স্থাপন করা put একক উদ্ধৃতি তাদের মধ্যে (ব্যাকস্ল্যাশ সহ) যে কোনও কিছুর বিস্তার রোধ করে; কেবলমাত্র তখনই আপনি যা করতে পারবেন না তা হ'ল প্যাটার্নে একক উদ্ধৃতি।

grep 'foo*' *.txt

আপনার যদি একটি একক উক্তি প্রয়োজন হয় তবে আপনি এটিকে লিখতে পারেন '\''(শেষ স্ট্রিং আক্ষরিক, আক্ষরিক উক্তি, ওপেন স্ট্রিং আক্ষরিক)।

grep 'foo*'\''bar' *.txt

দ্বিতীয়ত, গ্রেপ নিদর্শনগুলির জন্য দুটি বাক্য গঠনকে সমর্থন করে। পুরানো, ডিফল্ট সিনট্যাক্স ( বেসিক নিয়মিত এক্সপ্রেশন ) বিকল্প ( |) অপারেটরটিকে সমর্থন করে না , যদিও কিছু সংস্করণে এটি এক্সটেনশন হিসাবে রয়েছে তবে ব্যাকস্ল্যাশ দিয়ে লেখা রয়েছে।

grep 'foo\|bar' *.txt

বহনযোগ্য উপায়টি হল নতুন সিনট্যাক্স, বর্ধিত নিয়মিত এক্সপ্রেশনগুলি ব্যবহার করা । এটি নির্বাচন -Eকরতে grepআপনাকে বিকল্পটি পাস করতে হবে। লিনাক্সে, আপনি এর egrepপরিবর্তে টাইপ করতে পারেন grep -E(অন্যান্য ইউনিটগুলিতে, আপনি এটি একটি উপনাম তৈরি করতে পারেন)।

grep -E 'foo|bar' *.txt

আপনি যখন বেশ কয়েকটি নিদর্শনগুলির সন্ধান করছেন তখন অন্য একটি সম্ভাবনা (বিচ্ছিন্নতা ব্যবহার করে জটিল নকশা তৈরির বিপরীতে) একাধিক নিদর্শনগুলি পাস করা grep-eবিকল্পের সাথে প্রতিটি প্যাটার্নের আগে আপনি এটি করতে পারেন ।

grep -e foo -e bar *.txt

18
একটি সাইডনোট হিসাবে - নিদর্শনগুলি স্থির হয়ে গেলে, আপনার সত্যিকারের অভ্যাসে প্রবেশ করা উচিত fgrepবা grep -F, ছোট প্যাটার্নগুলির জন্য পার্থক্য নগণ্য হবে তবে সেগুলি দীর্ঘায়িত হওয়ার সাথে সাথে সুবিধাগুলি দেখাতে শুরু করবে ...
টিসি 1

7
@ টিসি 1 fgrep ম্যান পৃষ্ঠা অনুসারে
অবচয় করা হয়েছে

18
@ টিসি 1 এর grep -Fপ্রকৃত পারফরম্যান্স সুবিধা রয়েছে কিনা তা গ্রেপ বাস্তবায়নের উপর নির্ভর করে: তাদের মধ্যে কেউ কেউ যাই হোক না কেন একই অ্যালগরিদম প্রয়োগ করে, যাতে -Fকেবলমাত্র প্যাটার্নটি বিশ্লেষণ করতে ব্যয় করা সময়ের জন্য তাত্পর্য তৈরি হয় এবং সময় অনুসন্ধানের ক্ষেত্রে নয়। GNU গ্রেপটি দ্রুত নয় -F, উদাহরণস্বরূপ (এটিতে একটি grep -Fবাগও রয়েছে যা মাল্টবাইটি লোকেলগুলিতে ধীর করে তোলে - একই ধ্রুবক প্যাটার্নটি grepআসলে উল্লেখযোগ্যভাবে দ্রুত হয়!)। অন্যদিকে ব্যস্তবক্স গ্রেপ -Fবড় ফাইলগুলি থেকে প্রচুর উপকার করে।
গিলস

4
সম্ভবত এটি উল্লেখ করা উচিত যে আরও জটিল নিদর্শনগুলির জন্য যেখানে বিকল্পটি কেবল নিয়মিত অভিব্যক্তির একটি অংশের জন্য হয়, এটি "\ (" এবং "\)" দিয়ে ভাগ করা যায় (পালানো ডিফল্ট "বেসিক নিয়মিত অভিব্যক্তি" ) (?)।
পিটার মর্টেনসেন

4
মনে রাখবেন যে, egrepচেয়েও পুরনো grep -E। এটি জিএনইউ নির্দিষ্ট নয় (এটির লিনাক্সের সাথে অবশ্যই কোনও সম্পর্ক নেই)। আসলে, আপনি এখনও সোলারিসের মতো সিস্টেম পাবেন যেখানে ডিফল্ট grepএখনও সমর্থন করে না -E
স্টাফেন চেজেলাস

89
egrep "foo|bar" *.txt

অথবা

grep "foo\|bar" *.txt
grep -E "foo|bar" *.txt

নির্বাচিতভাবে gnu-grep এর ম্যান পৃষ্ঠাটি উদ্ধৃত করে:

   -E, --extended-regexp
          Interpret PATTERN as an extended regular expression (ERE, see below).  (-E is specified by POSIX.)

Matching Control
   -e PATTERN, --regexp=PATTERN
          Use PATTERN as the pattern.  This can be used to specify multiple search patterns, or to protect  a  pattern
          beginning with a hyphen (-).  (-e is specified by POSIX.)

(...)

   grep understands two different versions of regular expression syntax: basic and extended.”  In  GNU grep,  there
   is  no  difference  in  available  functionality  using  either  syntax.   In  other implementations, basic regular
   expressions are less powerful.  The following description applies to extended regular expressions; differences  for
   basic regular expressions are summarized afterwards.

শুরুতে আমি আরও পড়িনি, তাই আমি সূক্ষ্ম পার্থক্যগুলি চিনতে পারি নি:

Basic vs Extended Regular Expressions
   In basic regular expressions the meta-characters ?, +, {, |, (, and ) lose their special meaning; instead  use  the
   backslashed versions \?, \+, \{, \|, \(, and \).

আমি সর্বদা দরিদ্র এবং অযথা প্যারেন্স ব্যবহার করি, কারণ আমি উদাহরণগুলি থেকে শিখেছি। এখন আমি নতুন কিছু শিখেছি। :)


22

টিসি 1 যেমন বলেছে, -Fএটি ব্যবহারযোগ্য বিকল্প বলে মনে হচ্ছে:

$> cat text
some text
foo
another text
bar
end of file

$> patterns="foo
bar" 

$> grep -F "${patterns}" text
foo
bar

1
@ পয়েজ আমি f 'foo \ nbar' বিকল্প সম্পর্কে জানতাম না, এখানে সম্প্রসারণ কীভাবে কাজ করে তা নিশ্চিত নয়, সন্ধান করা প্রয়োজন, তবে আপনাকে ধন্যবাদ, এটি সত্যই কার্যকর।
হরিদসভ

নিস! এই বিকল্পটি এটিকে আরও দ্রুত চালিত করে তোলে বলে মনে হয় (যেহেতু এটি রেজেক্স অক্ষম করে)।
কিওয়ার্টজগুই

15

প্রথমত, আপনাকে বিশেষ অক্ষরের জন্য উদ্ধৃতিগুলি ব্যবহার করতে হবে। দ্বিতীয়ত, তবুও, grepসরাসরি বিকল্প বুঝতে পারবেন না; আপনার ব্যবহার করতে হবে egrep, বা ( grepকেবলমাত্র জিএনইউ সহ ) grep -E

egrep 'foo|bar' *.txt

(বিকল্পটি যদি কোনও বৃহত্তর রেজেসের অংশ না হয় তবে প্রথম বন্ধনীগুলি অপ্রয়োজনীয়))


4
আসলে, grep -Eতুলনায় আরও মান egrep
jw013

8

আপনি নিয়মিত এক্সপ্রেশন প্রয়োজন হবে না, এটা অনেক দ্রুত ব্যবহার করবেন তা fgrepবা grep -Fএকাধিক -e পরামিতি সঙ্গে, এভাবে:

fgrep -efoo -ebar *.txt

fgrep(বিকল্পভাবে grep -F) নিয়মিত গ্রেপের তুলনায় অনেক দ্রুত কারণ এটি নিয়মিত প্রকাশের পরিবর্তে স্থির স্ট্রিংগুলি অনুসন্ধান করে।


4
অনুগ্রহ করে এই পৃষ্ঠায় দেওয়া মন্তব্যগুলিও দেখুন fgrep
পিএইচকে

6

ফলাফল পেতে আপনি নীচের আদেশটি চেষ্টা করতে পারেন:

egrep 'rose.*lotus|lotus.*rose' some_file

3

একাধিক নিদর্শনগুলির জন্য গ্রেপ করার একটি সস্তা এবং প্রফুল্ল উপায়:

$ echo "foo" > ewq ; echo "bar" >> ewq ; grep -H -f ewq *.txt ; rm ewq

এটি একটি ব্যাখ্যা থেকে উপকৃত হতে পারে।
পিটার মর্টেনসেন

2
ব্যাখ্যাটি হ'ল গ্রেপের -fবিকল্পটি একাধিক নিদর্শন সহ একটি ফাইল নেয়। একটি অস্থায়ী ফাইল তৈরি করার পরিবর্তে (যে আপনি পরে মুছতে ভুলে যেতে পারেন), কেবল শেলের প্রক্রিয়া বিকল্পটি ব্যবহার করুন:grep -f <(echo foo; echo bar) *.txt
জাকব

3

পাইপ ( |) হ'ল একটি বিশেষ শেল অক্ষর, সুতরাং এটি থেকে পালাতে হবে ( \|) বা ম্যানুয়াল অনুসারে উদ্ধৃত করা ( man bash):

শেলটির নির্দিষ্ট অক্ষর বা শব্দের বিশেষ অর্থ সরিয়ে দিতে উদ্ধৃতি ব্যবহার করা হয় । এটি বিশেষ অক্ষরগুলির জন্য বিশেষ চিকিত্সা অক্ষম করতে, সংরক্ষিত শব্দগুলিকে এরূপ হিসাবে স্বীকৃতি থেকে রোধ করতে এবং প্যারামিটারের বিস্তার রোধ করতে ব্যবহার করা যেতে পারে।

ডাবল উদ্ধৃতিগুলিতে অক্ষরগুলি বদ্ধ করা কোটগুলির মধ্যে সমস্ত অক্ষরের আক্ষরিক মান সংরক্ষণ করে

একটি অ-উদ্ধৃত ব্যাকস্ল্যাশ ( \) হ'ল পালাবার চরিত্র।

দেখুন: বাশে কোন চরিত্রের পালাতে হবে?

এখানে কয়েকটি উদাহরণ (সরঞ্জামগুলি ব্যবহার করে এখনও উল্লেখ করা হয়নি):

  • ব্যবহার ripgrep:

    • rg "foo|bar" *.txt
    • rg -e foo -e bar *.txt
  • ব্যবহার git grep:

    • git grep --no-index -e foo --or -e bar

      দ্রষ্টব্য: এটি বুলিয়ান এক্সপ্রেশন যেমন --and, --orএবং সমর্থন করে --not

প্রতি লাইনে ও অপারেশনের জন্য, দেখুন: একাধিক এবং নিদর্শন সহ গ্রেপ কীভাবে চালানো যায়?

প্রতি ফাইলের জন্য এবং অপারেশনের জন্য, দেখুন: কোনও ফাইলে থাকা সমস্ত একাধিক স্ট্রিং বা রেজেক্সস কীভাবে পরীক্ষা করবেন?


3

আমার অ্যাক্সেস লগগুলি ছিল যেখানে তারিখগুলি নির্বোধ আকারে ফর্ম্যাট করা হয়েছিল: [30 / জুন / 2013: 08: 00: 45 +0200]

তবে আমার এটি হিসাবে প্রদর্শিত হবে: 30 / জুন / 2013 08:00:45

সমস্যাটি হ'ল আমার গ্রেপ স্টেটমেন্টে "OR" ব্যবহার করে, আমি দুটি পৃথক লাইনে দুটি ম্যাচের প্রকাশ পেয়েছিলাম।

সমাধান এখানে:

grep -in myURL_of_interest  *access.log  | \
grep -Eo '(\b[[:digit:]]{2}/[[:upper:]][[:lower:]]{2}/[[:digit:]]{4}|[[:digit:]]{2}:[[:digit:]]{2}:[[:digit:]]{2}\b)'   \
| paste - - -d" " > MyAccess.log

2

টিএল; ডিআর: যদি আপনি একাধিক নিদর্শনগুলির সাথে মেলানোর পরে আরও কিছু করতে চান, তবে সেগুলি এটিকে হিসাবে বন্ধ করুন \(pattern1\|pattern2\)

উদাহরণ: আমি এমন সব জায়গাগুলি সন্ধান করতে চাই যেখানে 'তারিখ' নামের একটি ভেরিয়েবল একটি স্ট্রিং বা ইন্ট হিসাবে সংজ্ঞায়িত হয়। (উদাঃ, "ইনট ক্রোনডেট =" বা "স্ট্রিং টেক্সট ফর্ম্যাটডেট স্ট্যাম্প ="):

cat myfile | grep '\(int\|String\) [a-zA-Z_]*date[a-zA-Z_]* =' 

এর সাথে grep -E, আপনাকে প্রথম বন্ধনী বা পাইপ এড়িয়ে চলার দরকার নেই, অর্থাৎ,grep -E '(int|String) [a-zA-Z_]*date[a-zA-Z_]* ='


1

এটি আমার পক্ষে কাজ করে

root@gateway:/home/sshuser# aws ec2 describe-instances --instance-ids i-2db0459d |grep 'STATE\|TAG'

**STATE**   80      stopped

**STATE**REASON     Client.UserInitiatedShutdown    Client.UserInitiatedShutdown: User initiated shutdown

**TAGS**    Name    Magento-Testing root@gateway:/home/sshuser#

1

এটি করার একাধিক উপায় রয়েছে।

  1. grep 'foo\|bar' *.txt
  2. egrep 'foo|bar' *.txt
  3. find . -maxdepth 1 -type f -name "*.txt" | xargs grep 'foo\|bar'
  4. find . -maxdepth 1 -type f -name "*.txt" | xargs egrep 'foo|bar'

তৃতীয় এবং চতুর্থ বিকল্পটি কেবল ফাইলগুলিতে গ্রেপ হবে এবং .txtতাদের নামে থাকা ডিরেক্টরিগুলি এড়াবে।
সুতরাং, আপনার ব্যবহারের ক্ষেত্রে হিসাবে, আপনি উপরে উল্লিখিত বিকল্পগুলির যে কোনওটি ব্যবহার করতে পারেন।
ধন্যবাদ !!


0

@ গাইকোসর এর উত্তরে যুক্ত করতে , আপনার যদি একাধিক নিদর্শন থাকে তবে এতে নীচের কমান্ডটি ব্যবহার করে আপনি ট্যাব এবং স্পেসও রাখেন

grep -E "foo[[:blank:]]|bar[[:blank:]]"

[[:blank:]]আর আর ক্যারেক্টার ক্লাস যেখানে স্থান বা ট্যাব চরিত্রের প্রতিনিধিত্ব করে

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.