গ্রেপ: তারকাচিহ্ন (*) সবসময় কাজ করে না


11

আমি যদি এমন কোনও দস্তাবেজ গ্রেপ করি যাতে নিম্নলিখিতটি থাকে:

ThisExampleString

... প্রকাশের জন্য This*Stringবা *String, কিছুই ফেরানো হয়নি। তবে This*আশানুরূপভাবে উপরের লাইনটি প্রদান করে।

উদ্ধৃতিতে অভিব্যক্তিটি আবদ্ধ কিনা তা কোনও পার্থক্য করে না।

আমি ভেবেছিলাম তারকাচিহ্নটি অজানা কয়েকটি অক্ষরকে নির্দেশ করে? এটি কেবলমাত্র প্রকাশের শুরুতে হলে কেন কাজ করবে? যদি এটি উদ্দেশ্যমূলক আচরণ হয়, তবে আমি এক্সপ্রেশনগুলির পরিবর্তে কী ব্যবহার করব This*Stringএবং *String?


কারণ এটি কীভাবে কাজ করে না রেজেক্স ... (বিশেষত: * != any number of unknown charactersডকটি পড়ুন
njzk2

উত্তর:


18

নিয়মিত অভিব্যক্তিতে একটি তারকাচিহ্নের অর্থ "পূর্ববর্তী উপাদান 0 বা তার বেশি বারের সাথে মেলা"।

আপনার বিশেষ ক্ষেত্রে grep 'This*String' file.txt, আপনি বলার চেষ্টা করছেন, "আরে, গ্রেপ, শব্দের সাথে আমার মিল করুন Thi, তারপরে ছোট হাতের sশূন্য বা তার বেশি বার, শব্দটির পরে String"। ছোট হাতের sকোথাও খুঁজে পাওয়া যায়নি Example, তাই গ্রেপ উপেক্ষা করে ThisExampleString

এর ক্ষেত্রে grep '*String' file.txt, আপনি বলছেন "গ্রেপ, শূন্য স্ট্রিংটি আমাকে মিলিয়ে দিন - আক্ষরিক কিছুই নয় - শব্দের পূর্ববর্তী String"। অবশ্যই, এটি ThisExampleStringপড়ার অনুমিত হয় না। ( অন্যান্য সম্ভাব্য অর্থ রয়েছে-E - আপনি পতাকা সহ এবং এর বাইরেও এটি চেষ্টা করতে পারেন - তবে এর অর্থগুলির মধ্যে কোনওটিই আপনি এখানে যা চান ঠিক তেমন কিছু নয়))

জেনে .মানে হলো "কোন একক অক্ষর", আমরা এটা করতে পারে: grep 'This.*String' file.txt। এখন গ্রেপ কমান্ড এটি সঠিকভাবে পড়বে: Thisতারপরে যেকোন চরিত্র (এএসসিআইআই অক্ষরের নির্বাচন হিসাবে এটি মনে করে) যেকোন বার পুনরাবৃত্তি করে, তারপরে String


6
বাশ-এ (এবং ইউনিক্সের বেশিরভাগ শেল) *একটি বিশেষ চরিত্র এবং এটি উদ্ধৃত করা উচিত বা পালাতে হবে উদাহরণস্বরূপ: grep 'This*String' file.txtবা এটি: grep This\*String file.txtঅপ্রত্যাশিত ফলাফলের দ্বারা অবাক হওয়ার মতো নয়।
পাবউক

2
@ পবুক শেলস, এটি *একটি ওয়াইল্ডকার্ড। গ্রেপ ইন, *একটি নিয়মিত এক্সপ্রেশন অপারেটর। দেখুন unix.stackexchange.com/q/57957/70524
muru

11
পাবউক ঠিক বলেছেন, কমান্ড চালানোর আগে ফাইলের নাম সম্প্রসারণ ঘটে; তুলনা strace grep .* file.txt |& head -n 1 এবং strace grep '.*' file.txt |& head -n 1। এছাড়াও আসলে grepকোন ইউনিকোড অক্ষর দিয়ে কাজ করে (যেমন echo -ne ⇏ | grep ⇏আউটপুট )
কস

1
@ সার্জ: আপনার এখানে উচ্চ খ্যাতি রয়েছে তাই আমি ভেবেছিলাম যে আমার অর্থ কী তা আপনি অবিলম্বে খেয়াল করবেন। ওপি প্রশ্ন ট্যাগ করেছে ব্যাশ তাই আমি অনুমান আলোচনা কমান্ড দ্বারা ব্যাখ্যা করা হয় bash। এর অর্থ হ'ল প্রথমে bashএটির বিশেষ অক্ষরগুলি ব্যাখ্যা করে এবং সমস্ত সম্পাদিত বিস্তারের পরে এটি প্রসারিত প্রক্রিয়াটিতে প্যারামিটারগুলি পাস করে। ----- উদাহরণস্বরূপ ব্যাশ এই কমান্ড প্রয়োগ করুন: grep This.\*String file.txtডিম হবে /bin/grep: এই পরামিতি 0 দিয়ে grep, 1: This.*String2: file.txt। লক্ষ্য করুন যে বাশ ব্যাকস্ল্যাশ সরিয়েছে এবং মূলত পালানো *আক্ষরিক অর্থে পাস হয়েছিল।
পাবউক

7
মজার (এবং বেশ কদর্য সমস্যা সমাধানের জন্য :) জিনিসটি হ'ল আপনার কমান্ডগুলি grep This.*String file.txtসাধারণত কাজ করবে কারণ সম্ভবত শেল ওয়াইল্ডকার্ড এক্সপ্রেশনটির সাথে মেলে এমন কোনও ফাইল থাকবে না This.*String। এই জাতীয় ক্ষেত্রে বাশ আক্ষরিকভাবে যুক্তিটি পাস করবে *
পাবউক

8

*মধ্যে BRE metacharacter 1 এস, ere 1 s এবং PCRE 1 গুলি ম্যাচ পূর্বে দলবদ্ধ প্যাটার্ন 0 বা আরো occurences (কোন দলবদ্ধ প্যাটার্ন পূর্ববর্তী হয় *metacharacter), পূর্ববর্তী অক্ষরে ক্লাসের 0 বা আরো occurences (ক অক্ষর বর্গ হলে *মেটাচ্যাক্টরের পূর্ববর্তী ) বা 0 বা পূর্বের চরিত্রের আরও উপস্থিতি (যদি না একটি শ্রেণিবদ্ধ প্যাটার্ন বা একটি অক্ষর শ্রেণি *মেটাচ্যাক্টারের আগের নয় );

এর অর্থ এই যে This*Stringপ্যাটার্নে, *মেটাচ্যারাক্টরটি কোনও শ্রেণিবদ্ধ প্যাটার্ন বা চরিত্র শ্রেণির দ্বারা পূর্ববর্তী নয়, *মেটাচ্যাক্টর 0 বা তার আগের অক্ষরের উপস্থিতিগুলির সাথে মেলে (এই ক্ষেত্রে sচরিত্রটি):

% cat infile               
ThisExampleString
ThisString
ThissString
% grep 'This*String' infile
ThisString
ThissString

যে কোনও চরিত্রের 0 বা ততোধিক ঘটনার সাথে মিল রাখতে, আপনি .মেটাচার্যাক্টরের 0 বা ততোধিক ঘটনার সাথে মিল রাখতে চান , যা কোনও চরিত্রের সাথে মেলে:

% cat infile               
ThisExampleString
% grep 'This.*String' infile
ThisExampleString

*BREs এবং Eres মধ্যে metacharacter সর্বদা "লোভী" হয়, অর্থাত্ এটা দীর্ঘতম ম্যাচ ম্যাচ হবে:

% cat infile
ThisExampleStringIsAString
% grep -o 'This.*String' infile
ThisExampleStringIsAString

এটি পছন্দসই আচরণ নাও হতে পারে; ক্ষেত্রে এটি না, আপনি চালু করতে পারেন grepএর PCRE ইঞ্জিন (ব্যবহার -Pবিকল্প) এবং যোগ ?metacharacter, যা যখন করা পর *এবং +metacharacters তাদের লালসা পরিবর্তন প্রভাব আছে:

% cat infile
ThisExampleStringIsAString
% grep -Po 'This.*?String' infile
ThisExampleString

1: বেসিক নিয়মিত এক্সপ্রেশন, বর্ধিত নিয়মিত এক্সপ্রেশন এবং পার্ল সামঞ্জস্যপূর্ণ নিয়মিত এক্সপ্রেশন


খুব তথ্যপূর্ণ উত্তরের জন্য আপনাকে ধন্যবাদ। তবে, আমি একটি পৃথক উত্তর বেছে নিয়েছি কারণ এটি সংক্ষিপ্ত এবং বুঝতে সহজ ছিল। এত বিস্তারিত সরবরাহের জন্য +1।
ট্রে

@ ট্রে আপনি স্বাগত জানাই। এটি ঠিক আছে, আমি সম্মত হই যে সম্ভবত এটি খুব জটিল ছিল এবং বিষয়টির সাথে খুব বেশি পরিচিত না এমন ব্যক্তির জন্য অনেক বেশি অনুমান করা হয়েছিল।
কোস

4

এখানে একটি ব্যাখ্যা লিঙ্ক পাওয়া যায় :

তারকাচিহ্ন " *" বলতে ওয়াইল্ডকার্ডিংয়ের মতো নিয়মিত প্রকাশে একই জিনিস বোঝায় না; এটি এমন একটি সংশোধক যা পূর্ববর্তী একক অক্ষর, বা মত [0-9] এর মত প্রকাশের ক্ষেত্রে প্রযোজ্য। একটি নক্ষত্রটি এর আগে শূন্য বা আরও বেশি কিছু মেলে। সুতরাং এক বা একাধিক বড় হাতের অক্ষরের সাথে মেলে এমন [A-Z]*কোনও অক্ষরের সাথে মিলিয়ে কোনও বড় বড় অক্ষরের সাথে [A-Z][A-Z]*মেলে।


1

*একটি বিশেষ একটি শেল উভয় অর্থ globbing চরিত্র ( "ওয়াইল্ডকার্ড") এবং একটি রেগুলার এক্সপ্রেশন হিসাবে metacharacter । আপনাকে অবশ্যই উভয়কে বিবেচনায় নিতে হবে, যদিও আপনি যদি আপনার নিয়মিত অভিব্যক্তিটি উদ্ধৃত করেন তবে আপনি শেলটিকে বিশেষভাবে চিকিত্সা করা থেকে আটকাতে পারবেন এবং এটি এটি অপরিবর্তিত রয়েছে কিনা তা নিশ্চিত করতে পারেন grep। যদিও ধারণা অনুসারে ধরণের অনুরূপ, *শেলটির অর্থ কী তা বোঝায় তার থেকে একেবারে আলাদা grep

প্রথমে শেলটি *একটি ওয়াইল্ডকার্ড হিসাবে আচরণ করে ।

তুমি বলেছিলে:

উদ্ধৃতিতে অভিব্যক্তিটি আবদ্ধ কিনা তা কোনও পার্থক্য করে না।

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

শেলটি *এমন কোনও অক্ষরের মুখোমুখি হয় যা উদ্ধৃত হয়নি , এটি "শূন্য বা অন্য কোনও চরিত্রের" অর্থ বোঝায় এবং সেই শব্দের পরিবর্তে ফাইলের নামের সাথে এটি যুক্ত করে যা প্যাটার্নের সাথে মেলে। (ফাইলগুলির নাম যে দিয়ে শুরু .বাদ দেওয়া হয় - আপনার প্যাটার্ন যদি না নিজেই দিয়ে শুরু হয় . বা । আপনার শেল কনফিগার করেছেন তাদের যাহাই হউক না কেন অন্তর্ভুক্ত করা) এই হিসাবে পরিচিত হয় globbing --and এছাড়াও নাম দ্বারা ফাইলের নাম সম্প্রসারণ এবং পথনাম সম্প্রসারণ

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

এটি কখনও কখনও কোনও সমস্যা না হওয়ার কারণ - এবং আপনার বিশেষ ক্ষেত্রে, কমপক্ষে এখনও পর্যন্ত , এটি ছিল না - এটি নীচের সমস্ত কিছু সত্য হলে* একা হয়ে যাবে :

  1. যার নাম মেলে এমন কোনও ফাইল নেই ... অথবা আপনি নিজের শেলটিতে গ্লোব্বিং অক্ষম করেছেন, সাধারণত set -fবা সমতুল্য set -o noglob। তবে এটি অস্বাভাবিক এবং আপনি সম্ভবত জানেন যে আপনি এটি করেছেন।

  2. আপনি কোনও শেল ব্যবহার করছেন যার ডিফল্ট আচরণটি *কোনও মিল নেই যখন কোনও ফাইলের নাম নেই alone বাশের ক্ষেত্রে এটি সম্ভবত আপনি ব্যবহার করছেন তবে বোর্ন-স্টাইলের সমস্ত শেল নয় in (উদাহরণস্বরূপ, জনপ্রিয় শেল জেডসে ডিফল্ট আচরণ গ্লোবগুলির জন্য হয় (ক) প্রসারিত করা বা (খ) একটি ত্রুটি তৈরি করা ) ) ... বা আপনি নিজের শেলের এই আচরণটি পরিবর্তন করেছেন - এটি কীভাবে হয় তারতম্য হয় শাঁস জুড়ে

  3. যদি না থাকে অন্যথায় globs সঙ্গে প্রতিস্থাপন করা দেওয়ার অনুমোদন চেয়ে আপনার শেল বলেন কিছুই আছে যখন আপনার সাথে মেলে এমন ফাইল, কিংবা এই অবস্থায় একটি ত্রুটির বার্তা সঙ্গে ব্যর্থ। বাশে এটি যথাক্রমে nullglobবা failglob শেল বিকল্পটি সক্ষম করেই করা হত ।

আপনি কখনও কখনও # 2 এবং # 3 উপর নির্ভর করতে পারেন তবে আপনি খুব কমই # 1 উপর নির্ভর করতে পারেন। grepএখন কাজ করে এমন একটি অব্যর্থিত প্যাটার্নযুক্ত একটি কমান্ড আপনার আলাদা ফাইল থাকতে পারে বা আপনি এটি অন্য কোনও জায়গা থেকে চালানোর সময় কাজ করা বন্ধ করে দিতে পারে। আপনার নিয়মিত অভিব্যক্তিটি উদ্ধৃত করুন এবং সমস্যাটি চলে যায়।

তারপরgrep কমান্ড একইরূপে *একটি কোয়ান্টিফায়ার হিসাবে।

অন্যান্য উত্তর - যেমন যারা Sergiy Kolodyazhnyy দ্বারা এবং কস দ্বারা কিছুটা ভিন্ন উপায়ে এই প্রশ্নের এই দৃষ্টিভঙ্গির --also ঠিকানা। সুতরাং আমি যারা এখনও এগুলি পড়েনি এখনও তাদের উত্তরটি পড়ার আগে বা পরে তা করার জন্য উত্সাহিত করছি।

ধরে নেওয়া যাক *এটা grep করতে নেই - যা উদ্ধৃত ensure-- উচিত grepতারপর, এটা মানে লাগে যে আইটেম আগে বসেছে সময়ের কোন সংখ্যা ঘটতে পারে বরং ঠিক একবার ঘটতে থাকার চেয়ে । এটি এখনও একবার হতে পারে। অথবা এটি সম্ভবত উপস্থিত নাও হতে পারে। বা এটি পুনরাবৃত্তি হতে পারে। পাঠ্য যে সঙ্গে তড়কা কোনো ঐ সম্ভাবনার সাথে মিলে যাবে।

আমি "আইটেম" বলতে কী বোঝাতে চাই?

  • একক চরিত্র । যেহেতু bম্যাচ একটি আক্ষরিক b, b*মিলে যায় শূন্য বা তার বেশি bগুলি, এইভাবে ab*cসাথে মিলে যায় ac, abc, abbc, abbbc, ইত্যাদি

    একইভাবে, যেহেতু .মেলা যেকোনো চরিত্র , .*শূন্য বা তার বেশি অক্ষরের সাথে মেলে 1 , এইভাবে a.*cম্যাচ ac, akc, ahjglhdfjkdlgjdfkshlgc, এমনকি acccccchjckhcc, ইত্যাদি অথবা

  • একটি চরিত্র শ্রেণি । যেহেতু [xy]ম্যাচ xবা y, [xy]*ম্যাচ বা তার বেশি অক্ষরের শূন্য যেখানে প্রতিটি এক হয় হয় xবা y, এইভাবে p[xy]*qসাথে মিলে যায় pq, pxq, pyq, pxxq, pxyq, pyxq, pyyq, pxxxq, pxxyq, ইত্যাদি

    এই ক্ষেত্রে প্রযোজ্য ফরম সাধারণভাবে সংক্ষেপে মত চরিত্র ক্লাস \w, \W, \s, এবং \S। যেহেতু যে \wকোনও শব্দের চরিত্রের সাথে \w*মেলে, শূন্য বা আরও শব্দের অক্ষরের সাথে মেলে। অথবা

  • একটি দল । যেহেতু \(bar\)ম্যাচ bar, \(bar\)*ম্যাচ শূন্য বা তার বেশি barগুলি, এইভাবে foo\(bar\)*bazসাথে মিলে যায় foobaz, foobarbaz, foobarbarbaz, foobarbarbarbaz, ইত্যাদি

    সঙ্গে -Eবা -Pবিকল্প, grepএকটি হিসাবে আপনার রেগুলার এক্সপ্রেশন একইরূপে ere বা PCRE যথাক্রমে বরং একটি হিসাবে চেয়ে BRE , এবং তারপর গ্রুপ দ্বারা বেষ্টিত করা হয় ( )পরিবর্তে \( \), তাই তারপর আপনি ব্যবহার করতে চাই (bar)পরিবর্তে \(bar\)এবং foo(bar)bazপরিবর্তে foo\(bar\)baz

man grepশেষে BRE এবং ERE সিনট্যাক্সের যুক্তিসঙ্গতভাবে অ্যাক্সেসযোগ্য ব্যাখ্যা দেয়, পাশাপাশি grepশুরুতে সমস্ত কমান্ড-লাইন বিকল্প গ্রহণ করে এমন তালিকা তৈরি করে। আমি সেই ম্যানুয়াল পৃষ্ঠাটিকে একটি উত্স হিসাবে, এবং জিএনইউ গ্রেপ ডকুমেন্টেশন এবং এই টিউটোরিয়াল / রেফারেন্স সাইটটি (যা আমি উপরের পৃষ্ঠাগুলির সাথে সংযুক্ত করেছি) সুপারিশ করি।

পরীক্ষা এবং শেখার জন্য grep, আমি এটি একটি প্যাটার্ন দিয়ে কল করার প্রস্তাব দিচ্ছি তবে কোনও ফাইল নাম নেই। তারপরে এটি আপনার টার্মিনাল থেকে ইনপুট নেয়। লাইন প্রবেশ করান; আপনার কাছে যে রেখাগুলি প্রতিধ্বনিত হয় সেগুলি হ'ল সেই পাঠ্য যা আপনার প্যাটার্নটি মেলে। প্রস্থান করতে, একটি লাইনের শুরুতে Ctrl+ টিপুন D, যা ইনপুটটির শেষের ইঙ্গিত দেয়। (অথবা আপনি বেশিরভাগ কমান্ড-লাইন প্রোগ্রামের মতো Ctrl+ টিপতে পারেন C)) উদাহরণস্বরূপ:

grep 'This.*String'

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

1 সুতরাং .*একটি নিয়মিত প্রকাশে *শেল গ্লোব বলতে কী বোঝায়। যাইহোক, পার্থক্যটি হ'ল grepস্বয়ংক্রিয়ভাবে লাইনগুলি মুদ্রণ করে যেগুলিতে সেগুলির যে কোনও জায়গায় আপনার মিল রয়েছে , তাই এটি .*নিয়মিত প্রকাশের শুরুতে বা শেষে হওয়া সাধারণত অপ্রয়োজনীয় ।

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