এন সংখ্যাগুলির গ্রুপগুলির জন্য গ্রেপ কীভাবে করবেন, তবে এন এর চেয়ে বেশি নয়?


33

আমি লিনাক্স শিখছি, এবং আমার একটি চ্যালেঞ্জ রয়েছে যা আমি নিজে থেকে সমাধান করতে ব্যর্থ বলে মনে করি। এটা এখানে:

একটি ফাইল থেকে একটি লাইন গ্রেপ করুন যার মধ্যে সারিতে 4 টি সংখ্যা রয়েছে তবে 4 এর বেশি নয়।

আমি কীভাবে এটি পৌঁছাতে পারি তা নিশ্চিত নই। আমি নির্দিষ্ট সংখ্যার জন্য অনুসন্ধান করতে পারি তবে কোনও স্ট্রিংয়ের পরিমাণে নয়।


2
একটি লাইনের মত 1234a12345প্রদর্শিত হওয়া উচিত, না?
এলিয়াহ কাগন

@ বুধাকে আপনার প্রশ্নের উদাহরণ সহ একটি ব্যাখ্যা দেওয়ার দরকার আছে।
অবিনাশ রাজ

যদি নম্বরগুলি স্পেসের আগে বা লাইন অ্যাঙ্কারের শুরু এবং তার পরে স্পেস বা লাইন অ্যাঙ্কারের শেষে হয় তবে আপনি কেবল শব্দের সীমানা ব্যবহার করতে পারেন। \b\d{4}\b
অবিনাশ রাজ

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

1
আপনাকে ধন্যবাদ সবাইকে, আমার এত ধারণা ছিলাম আমি জানতাম না। এই উত্তরটি আমি খুঁজছিলাম: গ্রেপ-ই '(^ | [^ 0-9]) [0-9] {4} ($ | [^ 0-9])' ফাইল। কমান্ডটি অবশ্যই এর মতো একটি স্ট্রিং টানতে সক্ষম হবে (যা এটি করে): abc1234abcd99999
বুদ্ধ

উত্তর:


52

এই প্রশ্নের ব্যাখ্যার দুটি উপায় রয়েছে; আমি উভয় ক্ষেত্রেই সম্বোধন করব। আপনি লাইনগুলি প্রদর্শন করতে চাইতে পারেন:

  1. এতে চারটি সংখ্যার ক্রম রয়েছে যা নিজেই অঙ্কগুলির আর কোনও ক্রমের অংশ নয় or
  2. এতে একটি চার-অঙ্কের ক্রম রয়েছে তবে অঙ্কগুলির ক্রম আর থাকবে না (এমনকি আলাদাভাবেও নয়)।

উদাহরণস্বরূপ, (1) প্রদর্শিত হবে 1234a56789, কিন্তু (2) তা করবে না।


আপনি যদি চারটি অঙ্কের ক্রমযুক্ত সমস্ত লাইন প্রদর্শন করতে চান যা নিজেই অঙ্কগুলির দীর্ঘতর ক্রমের অংশ নয় তবে একটি উপায় হ'ল:

grep -P '(?<!\d)\d{4}(?!\d)' file

এটি পার্ল নিয়মিত এক্সপ্রেশন ব্যবহার করে , যা উবুন্টু grep( জিএনইউ গ্রেপ ) মাধ্যমে সমর্থন করে -P। এটি এর মতো পাঠ্যের সাথে 12345মেলে না 1234বা 2345এটির অংশ বা এটির সাথে মেলে না। কিন্তু এটা ম্যাচ হবে 1234মধ্যে 1234a56789

পার্ল নিয়মিত প্রকাশে:

  • \dকোনও অঙ্ক মানে (এটি বলার একটি ছোট উপায় [0-9]বা [[:digit:]])।
  • x{4}x4 বার মেলে । ( { }সিনট্যাক্স পার্ল নিয়মিত এক্সপ্রেশনগুলির সাথে নির্দিষ্ট নয়; এটি বর্ধিত নিয়মিত এক্সপ্রেশনগুলির grep -Eমধ্যেও রয়েছে)) \d{4}একইভাবে \d\d\d\d
  • (?<!\d)শূন্য প্রস্থের নেতিবাচক চেহারা-পিছনে দৃ as়তা। এর অর্থ "আগে না থাকলে \d"।
  • (?!\d)শূন্য-প্রস্থের নেতিবাচক চেহারা-এগিয়ে উত্সাহ। এর অর্থ "অনুসরণ না করে \d"।

(?<!\d)এবং (?!\d)চার অঙ্কের ক্রমের বাইরে পাঠ্যের সাথে মেলে না; পরিবর্তে, তারা (যখন একত্রে ব্যবহৃত হবে) চারটি অঙ্কের ক্রমকে নিজের থেকে মিলে যাওয়া আটকাবে যদি এটি অঙ্কগুলির দীর্ঘতর ক্রমের অংশ হয়।

ডানদিকের বা বামদিকের চার-অঙ্কের পরবর্তী অংশটি এখনও মিলে যাবে কারণ কেবল চেহারা-পিছনে বা কেবল চেহারা-সামনের দিকে ব্যবহার করা অপর্যাপ্ত।

চেহারা-পিছনে এবং তাত্ক্ষণিক বক্তব্যগুলি ব্যবহার করার একটি সুবিধা হ'ল আপনার প্যাটার্নটি কেবল চার-অঙ্কের অনুক্রমগুলি নিজের সাথে মেলে, না পার্শ্ববর্তী পাঠ্যের সাথে। রঙ হাইলাইটিং ( --colorবিকল্প সহ) ব্যবহার করার সময় এটি সহায়ক ।

ek@Io:~$ grep -P '(?<!\d)\d{4}(?!\d)' <<< 12345abc789d0123e4
12345abc789d0123e4

ডিফল্টরূপে উবুন্টু, প্রত্যেক ব্যবহারকারী রয়েছে alias grep='grep --color=auto'তাদের মধ্যে ~.bashrcফাইল । সুতরাং আপনি যখন আপনি একটি সহজ দিয়ে শুরু কমান্ডটি প্রয়োগ স্বয়ংক্রিয়ভাবে হাইলাইট রঙ পেতে grep(এই যখন alias লেখা সম্প্রসারিত হয় নি) এবং মান আউটপুট হয় একটি টার্মিনাল (এই কি জন্য চেক)। ম্যাচগুলি সাধারণত লাল রঙের ছায়ায় ( সিঁদুরের কাছাকাছি ) হাইলাইট করা হয় তবে আমি এটি ইতালিযুক্ত সাহসের সাথে দেখিয়েছি। এখানে একটি স্ক্রিনশট:--color=auto
স্ক্রিনশটটি 12345abc789d0123e4 আউটপুট হিসাবে 0123 লাল রঙে হাইলাইট করে সেই গ্রেপ কমান্ডটি দেখায়।

এবং আপনি এমনকি grepএটির সাথে কেবল মেলে পাঠ্য, এবং পুরো লাইনটিও মুদ্রণ করতে পারবেন -o:

ek@Io:~$ grep -oP '(?<!\d)\d{4}(?!\d)' <<< 12345abc789d0123e4
0123

বিকল্প পন্থা, ছাড়া লুক-বিহাইন্ড এবং চেহারা-অ্যাহেড গবেষকেরা

তবে, যদি আপনি:

  1. একটি কমান্ড দরকার যা এমন সিস্টেমেও চলবে যেখানে grepসমর্থন করে না -Pবা অন্যথায় পার্ল নিয়মিত অভিব্যক্তি ব্যবহার করতে চায় না, এবং
  2. কি বিশেষভাবে চার ডিজিটের মেলা দরকার না - যা সাধারণত যদি হয় তাহলে আপনার লক্ষ্য প্রদর্শন ম্যাচ ধারণকারী লাইনে কেবল হয়, এবং
  3. একটি সমাধান যে ঠিক একটু মার্জিত হয় ঠিক আছে

... তারপরে আপনি এর পরিবর্তে বর্ধিত নিয়মিত প্রকাশের মাধ্যমে এটি অর্জন করতে পারেন :

grep -E '(^|[^0-9])[0-9]{4}($|[^0-9])' file

এটি চারটি সংখ্যার এবং অ-অঙ্কের অক্ষরের সাথে মেলে - বা লাইনটির শুরু বা শেষ - তাদের চারপাশে। বিশেষ করে:

  • [0-9]যেকোন অঙ্কের সাথে (যেমন [[:digit:]], বা \dপার্ল নিয়মিত এক্সপ্রেশনগুলিতে) মেলে এবং এর {4}অর্থ "চারবার"। সুতরাং [0-9]{4}একটি চার অঙ্কের ক্রম মেলে।
  • [^0-9]সীমার মধ্যে না অক্ষরের সাথে মেলে 0মাধ্যমে 9। এটি [^[:digit:]](বা \Dপার্ল নিয়মিত প্রকাশে) এর সমতুল্য ।
  • ^, যখন এটি [ ]বন্ধনীগুলিতে উপস্থিত হয় না , একটি লাইনের শুরুর সাথে মেলে। একইভাবে, $একটি লাইনের শেষের সাথে মেলে।
  • |অর্থ বা এবং প্রথম বন্ধনী গোষ্ঠীগুলির জন্য (বীজগণিত হিসাবে)। সুতরাং (^|[^0-9])লাইনটির শুরুতে বা একটি অ-অঙ্কের অক্ষরের সাথে ($|[^0-9])মেলে , যখন রেখার শেষে বা একটি অ-অঙ্কের অক্ষরের সাথে মেলে।

সুতরাং ম্যাচগুলি কেবলমাত্র চার-অঙ্কের ক্রম ( [0-9]{4}) যা একই সাথে থাকে:

  • লাইনের শুরুতে বা একটি অ-অঙ্কের পূর্বে ( (^|[^0-9])), এবং
  • লাইনের শেষে বা একটি অ-অঙ্কের পরে ( ($|[^0-9]))।

অন্যদিকে, আপনি যদি চারটি অঙ্কের ক্রমযুক্ত সমস্ত লাইন প্রদর্শন করতে চান তবে চারটি সংখ্যার বেশি কোনও অনুক্রম (এমনকি একটি মাত্র চারটি সংখ্যার অন্য ক্রম থেকে পৃথক এমন একটি) না রাখেন তবে ধারণাগতভাবে আপনার লক্ষ্য হ'ল এক প্যাটার্নের সাথে মেলে এমন লাইনগুলি খুঁজে পাওয়া যা অন্য নয়।

অতএব, আপনি যদি এটি একক প্যাটার্ন দিয়ে কীভাবে করতে পারেন তা জানার পরেও আমি ম্যাট-এর দ্বিতীয় পরামর্শ মতো কিছু ব্যবহার করার পরামর্শ দিই grep, দুটি প্যাটার্নের জন্য আলাদাভাবে আইএনএন তৈরি করা।

এটি করার সময় পার্ল নিয়মিত এক্সপ্রেশনগুলির কোনও উন্নত বৈশিষ্ট্য থেকে আপনি দৃ strongly়রূপে উপকার পাবেন না, তাই আপনি সেগুলি ব্যবহার না করা পছন্দ করতে পারেন। কিন্তু উপরে শৈলী সঙ্গে পালন, এখানে একটি সংক্ষেপিত এর অনুজ্জ্বল এর সমাধান ব্যবহার \dস্থানে (এবং ধনুর্বন্ধনী) [0-9]:

grep -P '\d{4}' file | grep -Pv '\d{5}'

যেহেতু এটি ব্যবহার করে [0-9], ম্যাট-এর উপায়টি আরও পোর্টেবল - এটি grepএমন সিস্টেমে কাজ করবে যেখানে পার্ল নিয়মিত অভিব্যক্তি সমর্থন করে না। আপনি যদি এর পরিবর্তে [0-9](বা [[:digit:]]) ব্যবহার করেন \dতবে ব্যবহার চালিয়ে যান { }, আপনি কিছুটা আরও সংক্ষিপ্ততার সাথে ম্যাটটির পোর্টেবিলিটি পাবেন:

grep -E '[0-9]{4}' file | grep -Ev '[0-9]{5}'

বিকল্প উপায়, একক প্যাটার্ন সহ

আপনি যদি সত্যিই কোনও grepআদেশ পছন্দ করেন

  1. একটি একক নিয়মিত অভিব্যক্তি ব্যবহার করে ( উপরে দুটি পাইপgrep দ্বারা পৃথক নয় )
  2. কমপক্ষে চার অঙ্কের এক সিকোয়েন্স যুক্ত লাইনগুলি প্রদর্শন করতে,
  3. তবে পাঁচটি (বা আরও) সংখ্যার কোনও অনুক্রম নেই,
  4. এবং আপনি পুরো অঙ্কটি মেলে মনে করবেন না, কেবল অঙ্কগুলি নয় (আপনি সম্ভবত এটি এতে আপত্তি করবেন না)

... তাহলে আপনি ব্যবহার করতে পারেন:

grep -Px '(\d{0,4}\D)*\d{4}(\D\d{0,4})*' file

-xপতাকা তোলে grepশুধুমাত্র লাইন প্রদর্শন যেখানে সমগ্র লাইন ম্যাচ (বদলে কোন লাইন ধারণকারী একটি ম্যাচ)।

আমি একটি পার্ল নিয়মিত এক্সপ্রেশন ব্যবহার করেছি কারণ আমি মনে করি এই ক্ষেত্রে সংক্ষিপ্তসার \dএবং \Dউল্লেখযোগ্যভাবে স্পষ্টতা বাড়িয়েছে। তবে এমন সিস্টেমে যেখানে পোর্টেবল কিছু দরকার grepনেই যেখানে সমর্থন করে না -P, আপনি সেগুলি [0-9]এবং [^0-9](অথবা সাথে [[:digit:]]এবং [^[:digit]]) এর সাথে প্রতিস্থাপন করতে পারেন :

grep -Ex '([0-9]{0,4}[^0-9])*[0-9]{4}([^0-9][0-9]{0,4})*' file

এই নিয়মিত প্রকাশের উপায়টি হ'ল:

  • মাঝখানে, \d{4}বা [0-9]{4}চার অঙ্কের এক ক্রম মেলে। আমাদের এর মধ্যে একটিরও বেশি থাকতে পারে তবে আমাদের কমপক্ষে একটি থাকা দরকার।

  • বাম দিকে, (\d{0,4}\D)*বা ([0-9]{0,4}[^0-9])*শূন্য বা আরও বেশি ( *) এর চেয়ে বেশি সংখ্যার চারটি সংখ্যার নয় এবং তারপরে একটি অ-সংখ্যাটি অনুসরণ করবে। জিরো ডিজিট (অর্থাত্ কিছুই নয়) "চার অঙ্কের বেশি নয়" এর একটি সম্ভাবনা। এটি (ক) খালি স্ট্রিং বা (খ) কোনও স্ট্রিং অ-অঙ্কে শেষ হওয়া এবং চারটি সংখ্যার বেশি কোনও সিকোয়েন্স যুক্ত না করে matches

    যেহেতু কেন্দ্রীয় \d{4}(বা [0-9]{4}) এর বাম দিকে অবিলম্বে পাঠ্যটি খালি হতে হবে বা একটি অ-অঙ্কের সাথে শেষ হতে হবে, এটি কেন্দ্রটিকে \d{4}চারটি সংখ্যার সাথে মিলিয়ে বাধা দেয় যা কেবল তাদের বামে অন্য (পঞ্চম) সংখ্যার সাথে মেলে।

  • ডানদিকে, (\D\d{0,4})*বা ([^0-9][0-9]{0,4})*শূন্য বা আরও বেশি ( *) এর সাথে মিল রাখে অ-অঙ্কের পরে চারটি অঙ্কের বেশি নয় (যা আগের মতো, চার, তিন, দুই, এক, এমনকি কোনওটিই হতে পারে না)। এটি (ক) খালি স্ট্রিং বা (খ) কোনও স্ট্রিং কোনও অ-অঙ্কের সাথে শুরু হওয়া এবং চারটি সংখ্যার বেশি কোনও সিকোয়েন্স যুক্ত না করে matches

    যেহেতু কেন্দ্রীয় \d{4}(বা [0-9]{4}) এর ডানদিকে অবিলম্বে পাঠ্যটি খালি থাকতে হবে বা একটি অ-অঙ্কের সাথে শুরু করা উচিত, এটি কেন্দ্রটিকে \d{4}চারটি সংখ্যার সাথে মিলে যাওয়া থেকে বিরত রাখে যার ঠিক ডানদিকে অন্য (পঞ্চম) অঙ্ক রয়েছে।

এটি নিশ্চিত করে যে চার-অঙ্কের ক্রমটি কোথাও উপস্থিত রয়েছে এবং পাঁচ বা ততোধিক সংখ্যার কোনও অনুক্রম কোথাও উপস্থিত নেই।

এইভাবে এটি করা খারাপ বা ভুল নয়। তবে সম্ভবত এই বিকল্পটি বিবেচনা করার সর্বাধিক গুরুত্বপূর্ণ কারণ এটি উপরের এবং ম্যাট-এর উত্তর অনুসারে পরিবর্তিত (বা অনুরূপ) ব্যবহারের সুবিধাটি স্পষ্ট করে ।grep -P '\d{4}' file | grep -Pv '\d{5}'

সেভাবে এটি পরিষ্কার হয়ে গেছে যে আপনার লক্ষ্যটি এমন লাইনগুলি নির্বাচন করা যা একটি জিনিস রাখে তবে অন্যটি নয়। প্লাস সিনট্যাক্স আরও সহজ (তাই এটি অনেক পাঠক / রক্ষণাবেক্ষণকারীদের দ্বারা আরও দ্রুত বোঝা যেতে পারে)।


9

এটি আপনাকে পরপর 4 নম্বর প্রদর্শন করবে তবে আরও বেশি নয়

grep '[0-9][0-9][0-9][0-9][^0-9]' file

Note এর অর্থ নোট করুন

এটির সাথে সমস্যা আছে যদিও আমি কীভাবে ঠিক করব তা নিশ্চিত নই ... সংখ্যাটি যদি লাইনের শেষ হয় তবে এটি প্রদর্শিত হবে না।

এই uglier সংস্করণ তবে এই ক্ষেত্রে কাজ করবে

grep '[0-9][0-9][0-9][0-9]' file | grep -v [0-9][0-9][0-9][0-9][0-9]

ওহো, এড্রেপ হওয়ার দরকার নেই - আমি এটি সম্পাদনা করেছি
ম্যাট

2
প্রথমটি ভুল - এটি সন্ধান করে a12345bকারণ এটি মেলে 2345b
ভোলকার সিগেল

0

যদি grepপার্ল নিয়মিত এক্সপ্রেশন ( -P) সমর্থন করে না , তবে নিম্নলিখিত শেল কমান্ডটি ব্যবহার করুন:

grep -w "$(printf '[0-9]%.0s' {1..4})" file

যেখানে printf '[0-9]%.0s' {1..4}4 বার উত্পাদন করা হবে [0-9]। এই পদ্ধতিটি কার্যকর, যখন আপনি দীর্ঘ সংখ্যা পেয়েছেন এবং আপনি প্যাটার্নটি পুনরাবৃত্তি করতে চান না (কেবল সন্ধানের 4জন্য আপনার সংখ্যাগুলির সাথে প্রতিস্থাপন করুন )।

ব্যবহার -wকরে পুরো শব্দটির সন্ধান করবে। তবে আপনি যদি আলফানামুরিক স্ট্রিংগুলিতে আগ্রহী হন তবে যেমন প্যাটার্নের শেষে 1234aযুক্ত করুন [^0-9], যেমন

grep "$(printf '[0-9]%.0s' {1..4})[^0-9]" file

ব্যবহার $()করা মূলত একটি কমান্ড প্রতিস্থাপন । কীভাবে প্যাটার্নটির পুনরাবৃত্তি হয় তা দেখতে এই পোস্টটি দেখুন printf


0

আপনি fileআপনার সিস্টেমে প্রকৃত ফাইলের নামটি প্রতিস্থাপন করে কমান্ডের নীচে চেষ্টা করতে পারেন :

grep -E '(^|[^0-9])[0-9]{4}($|[^0-9])' file

আপনি গ্রেপ কমান্ডের আরও ব্যবহারের জন্য এই টিউটোরিয়ালটি পরীক্ষা করতে পারেন ।

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