দুটি নির্দিষ্ট অক্ষর বা স্ট্রিংয়ের মধ্যে পাঠ্য সন্ধান করা


17

বলুন আমার এর মতো লাইন রয়েছে:

*[234]*
*[23]*
*[1453]*

যেখানে *কোনও স্ট্রিং প্রতিনিধিত্ব করে (ফর্মের একটি স্ট্রিং ব্যতীত [number])। কমান্ড লাইন ইউটিলিটি দিয়ে আমি এই লাইনগুলি পার্স করতে পারি এবং বন্ধনীগুলির মধ্যে সংখ্যাটি বের করতে পারি?

আরো সাধারণভাবে, এই সরঞ্জামগুলি যা cut, sed, grepবা awkএই ধরনের কাজের জন্য উপযুক্ত হবে?

উত্তর:


16

আপনার যদি জিএনইউ গ্রেপ থাকে তবে আপনি -oএকটি রেইগেক্স অনুসন্ধান করতে তার বিকল্পটি ব্যবহার করতে পারেন এবং কেবলমাত্র মিলে যাওয়া অংশটি আউটপুট করতে পারেন । (অন্যান্য গ্রেপ বাস্তবায়ন কেবল পুরো লাইনটিই প্রদর্শন করতে পারে)) যদি এক লাইনে বেশ কয়েকটি মিল থাকে তবে সেগুলি পৃথক লাইনে মুদ্রিত হয়।

grep -o '\[[0-9]*\]'

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

grep -P -o '(?<=\[)[0-9]*(?=\])'

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

sed -n 's/^.*\(\[[0-9]*\]\).*/\1/p'

বা যদি আপনি কেবল ডিজিটগুলি চান না বন্ধনীগুলি:

sed -n 's/^.*\[\([0-9]*\)\].*/\1/p'

ছাড়া grep -o, পার্ল এখানে পছন্দের হাতিয়ার যদি আপনি এমন কিছু চান যা সাধারণ এবং বোধগম্য। প্রতিটি লাইনে ( -n), লাইনটিতে যদি কোনও মিল থাকে \[[0-9]*\]তবে সেই ম্যাচটি ( $&) এবং একটি নতুন লাইন ( -l) মুদ্রণ করুন ।

perl -l -ne '/\[[0-9]*\]/ and print $&'

আপনি যদি কেবল ডিজিটগুলি চান তবে একটি দলকে সীমানা নির্ধারণ করতে রেগেক্সে প্রথম বন্ধনী লিখুন এবং কেবলমাত্র সেই গোষ্ঠীটি মুদ্রণ করুন।

perl -l -ne '/\[([0-9]*)\]/ and print $1'

পিএস যদি আপনি কেবল বন্ধনীগুলির মধ্যে এক বা একাধিক সংখ্যার প্রয়োজন হয়, পরিবর্তন [0-9]*করতে পারেন [0-9][0-9]*বা [0-9]+পার্লে।


সব ভাল, তিনি ব্যতীত " ব্র্যাকেটের মধ্যে সংখ্যাটি বের করতে" চান । আমি মনে করি "ব্যতীত [number]" অর্থ ব্যতীত[0-9]
পিটার.ও

1
@ পিটার.ও আমি "[সংখ্যা] ব্যতীত" বোঝার অর্থ বুঝিয়েছি যে সেই ফর্মের লাইনের অন্য অংশ নেই। তবে আমি কীভাবে কেবলমাত্র অঙ্কগুলি মুদ্রণ করব তা দেখানোর জন্য আমার উত্তর সম্পাদনা করেছি ited
গিলস 'তাই খারাপ হওয়া বন্ধ করুন'

1
সেই perlরিজেক্স অ্যাসেটগুলি সত্যই দরকারী মনে হচ্ছে! আপনি পশ্চাৎ এবং সামনের দিকের উভয়ই, এমনকি গ্রেপ-তেও ব্যবহার করার পরে আমি সেগুলি সম্পর্কে পড়ছি (আমি আপনাকে সত্যিকার অর্থে রিজেক্স ইঞ্জিনটি বেছে নিতে পারি তা সত্য করেছিলাম)। আমি এখান থেকে পার্লের রেজেক্সের জন্য আরও কিছুটা সময় ব্যয় করব। ধন্যবাদ ... পিএস .. আমি সবেই পড়েছি man grep... "এটি অত্যন্ত পরীক্ষামূলক এবং গ্রেপ-পি অ-প্রয়োগীয় বৈশিষ্ট্যগুলির বিষয়ে সতর্ক করতে পারে।" ... আমি আশা করি যে নেই গড় অস্থির ... (?)
Peter.O

5

আপনি এটি দিয়ে করতে পারবেন না cut

  1. tr -c -d '0123456789\012'
  2. sed 's/[^0-9]*//g'
  3. awk -F'[^0-9]+' '{ print $1$2$3 }'
  4. grep -o -E '[0-9]+'

tr সমস্যাটির জন্য সবচেয়ে প্রাকৃতিক ফিট এবং সম্ভবত এটি দ্রুততম চলবে তবে আমি মনে করি গতির দিক থেকে এই বিকল্পগুলির মধ্যে যে কোনও একটি পৃথক করতে আপনার বিশাল ইনপুটগুলির প্রয়োজন হবে।


সিডের জন্য, ^.*লোভী এবং শেষ ডিজিট ব্যতীত সমস্তই গ্রাস করে, এবং পসিক্সটি ব্যবহার +করা \+বা অন্যথায় হওয়া দরকার \([0-9][0-9]*\).... এবং যে কোনও ক্ষেত্রে 's/[^0-9]*//g'যেমন ঠিক তেমনি কাজ করে, ... Thanks for the ত্রি-উদাহরণ উদাহরণস্বরূপ, তবে কি এটি \012অনুবর্তনকারী অতিমাত্রায় নয়?
পিটার.ও

@ পিটার এটি ধরার জন্য ধন্যবাদ আমি শপথ করেছিলাম আমি এর উদাহরণ উদাহরণ পরীক্ষা। :( আমি এটিকে আপনার সংস্করণে পরিবর্তন করেছি Regarding সম্পর্কিত \012: এটি অন্যথায় trনতুন লাইনগুলি খাওয়া দরকার
কাইল জোনস

আহা ... আমি এটি হিসাবে দেখছিলাম \0, 1, 2(এমনকি \, 0, 1, 2)। আমি মনে করি অষ্টাল তেমন একাগ্র নন, ধন্যবাদ .. ধন্যবাদ
পিটার.ও

4

যদি আপনি বোঝাতে চান অ অ-অঙ্কিত অক্ষরের মধ্যে একটানা সংখ্যার সেট বের করেন তবে আমার ধারণা sedএবং awkসর্বোত্তম (যদিও grepএটি আপনাকে মিলে যাওয়া চরিত্রগুলি দিতে সক্ষম):

sed: আপনি অবশ্যই অঙ্কগুলি মেলাতে পারবেন তবে বিপরীতটি করা সম্ভবত আকর্ষণীয়, অ-অঙ্কগুলি সরিয়ে ফেলুন (প্রতি লাইনে কেবলমাত্র একটি সংখ্যা রয়েছে):

$ echo nn3334nn | sed -e 's/[^[[:digit:]]]*//g'
3344

grep: আপনি একটানা সংখ্যার সাথে মেলাতে পারেন

$ echo nn3334nn | grep -o '[[:digit:]]*'
3344

আমি এর উদাহরণ দিচ্ছি না awkকারণ এর সাথে আমার নালীর অভিজ্ঞতা আছে; এটি লক্ষণীয় আকর্ষণীয় যে, যদিও sedএটি একটি সুইস ছুরি, grepএটি করার জন্য আপনাকে একটি সহজ এবং আরও পঠনীয় উপায় দেয় যা প্রতিটি ইনপুট লাইনে একাধিক সংখ্যার জন্যও কাজ করে ( -oএকমাত্র ইনপুটের মিলের অংশগুলি মুদ্রণ করে) নিজস্ব লাইনে):

$ echo dna42dna54dna | grep -o '[[:digit:]]*'
42
54

একটি তুলনা হিসাবে, এখানে "প্রতি লাইনে একাধিক সংখ্যার" উদাহরণের একটি sedevivalent রয়েছে । । । ... (+1)grep -o '[[:digit:]]*'sed -nr '/[0-9]/{ s/^[^[0-9]*|[^0-9]*$//g; s/[^0-9]+/\n/g; p}'
পিটার.ও

2

যেহেতু বলা হয়ে থাকে যে এটি দিয়ে করা যায় না cut, তাই আমি দেখাব যে সহজেই এমন একটি সমাধান তৈরি করা সম্ভব যা অন্যের কারও চেয়ে কম খারাপ না, যদিও আমি cut"সেরা" হিসাবে ব্যবহারকে সমর্থন করি না (বা এমনকি একটি বিশেষ ভাল) সমাধান। এটি বলা উচিত যে অঙ্কগুলির সুনির্দিষ্টভাবে *[এবং ]*আশেপাশে অনুসন্ধান না করা কোনও সমাধানই অনুমানকে সহজতর করে তোলে এবং অতএব প্রশ্নকারীর দেওয়া উদাহরণগুলির চেয়ে উদাহরণের তুলনায় ব্যর্থতার ঝুঁকিতে থাকে (যেমন অঙ্কগুলি বাইরে *[এবং ]*যা প্রদর্শিত হবে না)। এই দ্রষ্টব্যটি কমপক্ষে বন্ধনীগুলির জন্য পরীক্ষা করে এবং এটি asterisks পরীক্ষা করার জন্যও বাড়ানো যেতে পারে (পাঠকের কাছে অনুশীলন হিসাবে রেখে গেছে):

cut -f 2 -d '[' myfile.txt | cut -f 1 -d ']'

এটি -dবিকল্পটি ব্যবহার করে , যা একটি ডিলিমিটার নির্দিষ্ট করে। স্পষ্টতই আপনি cutকোনও ফাইল থেকে পড়ার পরিবর্তে অভিব্যক্তিটিও পাইপ করতে পারেন । যদিও cut, বেশ দ্রুত সম্ভবত যেহেতু এটা সহজ (কোন Regex ইঞ্জিন) চলে এলে, আপনি ডাকা আছে কমপক্ষে দুইবার (অথবা জন্য চেক করতে আরো কয়েকটি সময়ে *), যা কিছু পদ্ধতির ওভারহেড তৈরি করে। এই সমাধানটির একটি আসল সুবিধা হ'ল এটি বরং পাঠযোগ্য, বিশেষত নৈমিত্তিক ব্যবহারকারীদের জন্য যারা রেজেক্স কনস্ট্রাকশনে পারদর্শী নয়।

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