লাইনের শুরুতে বা মাঝখানে প্যাটার্নের জন্য গ্রেপ করুন


9

আমি এই কথাটি বলতে শুরু করব যে আমি মনে করি এই সমস্যাটি যতটা কম মনে হচ্ছে তার চেয়ে খানিকটা নিরীহ।

আমাকে যা করতে হবে: PATH এনভায়রনমেন্ট ভেরিয়েবলের মধ্যে একটি ফোল্ডার পরীক্ষা করুন। এটি শুরুতে বা অন্য কোথাও হতে পারে। আমাকে কেবল যাচাই করতে হবে যে সেই ফোল্ডারটি রয়েছে।

আমার সমস্যার উদাহরণ - আসুন ব্যবহার করি /opt/gnome


স্কেনারিও 1: ফোল্ডারটি প্যাথের শুরুতে নয়

# echo "$PATH"
/sbin:/usr/sbin:/opt/gnome:/var/opt/gnome

# echo "$PATH" | grep ":/opt/gnome"
/sbin:/usr/sbin:/opt/gnome:/var/opt/gnome

নোট করুন যে গ্রেপটি যথেষ্ট নির্দিষ্ট হওয়া দরকার যাতে এটি ধরা না পড়ে /var/opt/gnome। সুতরাং কোলন।


স্কেনারিও 2: ফোল্ডারটি প্যাথের শুরুতে।

# echo "$PATH"
/opt/gnome:/sbin:/usr/sbin:/var/opt/gnome

# echo "$PATH" | grep "^/opt/gnome"
/opt/gnome:/sbin:/usr/sbin:/var/opt/gnome

এটি আমার সমস্যা - আমার এই ফোল্ডারটি দিয়ে কোনও কোলন বা একটি শুরুর লাইন অনুসন্ধান করতে হবে। আমি যা করতে চাই তা হল এই দুটি বন্ধনী এক্সপ্রেশনগুলির মধ্যে একটি:

# echo $PATH | grep "[^:]/opt/gnome"
# echo $PATH | grep "[:^]/opt/gnome"

কিন্তু [^[:তাদের নিজস্ব অর্থ আছে। সুতরাং উপরের দুটি কমান্ড কাজ করে না not

একটি কমান্ডে এই দুটি পরিস্থিতিতে আমি গ্রেপ করতে পারি এমন কোন উপায় আছে কি?


নোট করুন যে কস্টাসের উত্তরের বিষয়ে গিলসের মন্তব্য এই প্রশ্নের ক্ষেত্রেও প্রযোজ্য: আপনি যেহেতু ঝাঁপিয়ে পড়ছেন না /opt/gnome:বা তাই /opt/gnome$, আপনি খুঁজে পাবেন /opt/gnome-fooবা পাবেন /opt/gnome/bar
স্কট

@ স্কট - যতক্ষণ না আপনি আপনার ম্যাচের মধ্যস্থতাকারী স্থানটিকে অন্তর্ভুক্ত করবেন ততক্ষণ আপনি এ জাতীয় জটিলতা ছাড়াই সর্বদা লাইন এর মাথা এবং লেজের কোনও স্ট্রিং নোঙ্গর করতে পারেন। ঠিক যেমনgrep '^\(any number of other matches:*:\)*my match\(:.*\)*$'
মাইকজার্ভ

উত্তর:


10

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

ব্যাশ, কেশ এবং জেডএসে:

if [[ :$PATH: = *:/opt/gnome:* ]]; then
 : # already there
else
  PATH=$PATH:/opt/gnome
fi

Portably:

case :$PATH: in
  *:/opt/gnome:*) :;; # already there
  *) PATH=$PATH:/opt/gnome;;
esac

:$PATH:পরিবর্তে ব্যবহার নোট করুন $PATH; এইভাবে, উপাদানটি সর্বদা অনুসন্ধান স্ট্রিংয়ে কোলন দ্বারা বেষ্টিত থাকে এমনকি এটি শুরুতে বা শেষে থাকলেও $PATH

যদি আপনি কোনও ফাইলের একটি লাইন অনুসন্ধান করে থাকেন তবে আপনি মিলিত হওয়ার জন্য বর্ধিত রেজিএক্সপ্যাক্স (অর্থাত্ প্রয়োজনীয় grep -E) ব্যবহার করতে পারবেন তবে কেবল এটি লাইনটির শুরুতে বা কোনও কোলন অনুসরণ করলেই হয়, এবং কেবলমাত্র এটি যদি হয় শেষে থাকে লাইন বা তার পরে একটি কোলন।(^|:)/opt/gnome($|:)/opt/gnome


8

আপনি কেবল ব্যবহার করে বর্ধিত নিয়মিত এক্সপ্রেশন ব্যবহার করতে পারেন grep -E

আপনি যদি মিথ্যা ধনাত্মকতা এড়াতে চান তবে আপনি যে পথটির চেষ্টা করছেন তার শুরু এবং শেষের সাথে মিল রাখতে হবে।

শুরুতে উদাহরণটির সাথে মেলে:

$ TEST=/opt/gnome:/sbin:/usr/sbin:/var/opt/gnome
$ echo $TEST | grep -E "(:|^)/opt/gnome(:|$)"
/opt/gnome:/sbin:/usr/sbin:/var/opt/gnome

মাঝখানে উদাহরণটিও মেলে:

$ TEST=/sbin:/usr/sbin:/opt/gnome:/var/opt/gnome
$ echo $TEST | grep -E "(:|^)/opt/gnome(:|$)"
/sbin:/usr/sbin:/opt/gnome:/var/opt/gnome

মিথ্যা ধনাত্মকতা এড়ানো:

$ TEST="/home/bob/opt/gnome:/opt/gnome/somethingelse:/opt/gnome-beta"
$ echo $TEST | grep -E "(:|^)/opt/gnome(:|$)"

সেখানে কোনও মিল নেই।

কমপ্যাক্ট এবং মার্জিত। ডেবিয়ান 7 এ পরীক্ষিত।


1
egrepঅবমানিত ব্যবহার grep -E(উত্স man grep:)
অ্যান্থন

ধন্যবাদ, একটি মোহন মত কাজ করে! যদিও আমি এটিকে উত্তর হিসাবে বেছে নিইনি, কারণ আমি মনে করি -উ বিকল্পটি কিছুটা সহজ more এর চেয়েও সহজ আমি কল্পনা করেছিলাম!
জেমসএল

3
সতর্কবাণী। -wবিকল্প কিছু সমস্যা রয়েছে। কেবলমাত্র অঙ্ক, অক্ষর এবং আন্ডারস্কোরকে "শব্দ" হিসাবে বিবেচনা করা হয়। সুতরাং কিছু অস্বাভাবিক তবে সম্ভাব্য অক্ষর এটিকে ব্যর্থ করে দেবে। উদাহরণ echo '/sbin:/usr/sbin:/var-/opt/gnome' | grep -w "/opt/gnome"এবং echo '/sbin:/usr/sbin:/var./opt/gnome' | grep -w "/opt/gnome"। যারা ভুল ফলাফল দেয়।
লুইস আন্তোলান ক্যানো

1
তুমি কি সঠিক পথে, কিন্তু এখনও মিথ্যা positives আছেন: /opt/gnome/somethingelse
গিলস 'তাই মন্দ হওয়া বন্ধ করুন'

1
পুরোপুরি ঠিক। আমাদের শুরু সম্পর্কে নয়, স্পষ্টভাবে শেষ হওয়া উচিত care আমি মনে করি এটি সমস্যার সমাধান করে echo "/home/bob/opt/gnome:/opt/gnome/somethingelse:/opt/gnome-beta" | grep -E "(:|^)/opt/gnome(:|$)"। উত্তর সম্পাদনা করা হচ্ছে।
লুইস আন্তোলন ক্যানো

7

আপনি যদি বিবাহ বন্ধনে আবদ্ধ না হন তবে আপনি রেকর্ডগুলি grepব্যবহার করে awkআলাদা করতে পারেন:

awk 'BEGIN {RS=":"} /^\/opt\/gnome$/'

5

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

echo "$PATH" | tr ':' '\n' | grep -x "/opt/gnome"

যা পাথ-ভেরিয়েবলকে পৃথক রেখায় বিভক্ত করে (প্রতিটি পথ প্রতি এক), সুতরাং grep -xসঠিক ফলাফলের সন্ধান করতে পারে। এটির জন্য অবশ্যই এটির অসুবিধা রয়েছে যেটির জন্য এটি একটি অতিরিক্ত প্রক্রিয়া প্রয়োজন tr। এবং যখন কোনও ফোল্ডারের PATHনামটিতে নতুন লাইন অক্ষর থাকে তখন এটি কাজ করবে না ।


2

আমি জানি না এটি উত্তরের পক্ষে যথেষ্ট কিন্তু তবে

grep -w "/opt/gnome"

আপনার প্রয়োজন মেটাবে

echo '/sbin:/usr/sbin:/opt/gnome:/var/opt/gnome' | grep -w "/opt/gnome" -o
/opt/gnome
echo '/opt/gnome:/sbin:/usr/sbin:/var/opt/gnome' | grep -w "/opt/gnome" -o
/opt/gnome

কিন্তু

echo '/opt/gnome:/sbin:/usr/sbin:/var/opt/gnome' | grep "/opt/gnome" -o
/opt/gnome
/opt/gnome

এটি নিখুঁতভাবে কাজ করে কারণ কলনগুলি অ-শব্দযুক্ত অক্ষর। ধন্যবাদ!
জেমসএল

@ স্ম্যান 865 এর অন্যান্য কারণও রয়েছে: কারণ /শব্দের একটি অংশ নয় rতবে।
কোস্টাস

2
সতর্কবাণী। আমি যেমন আমার মন্তব্যে মন্তব্য করেছি। ডিরেক্টরি নামের জন্য আইনী অক্ষর রয়েছে যা শব্দের অক্ষর নয়। এটি ভুল ফলাফল হতে পারে। ডিরেক্টরি ডিরেক্টরি শেষ করা স্বাভাবিক নয় - তবে এটি ঘটতে পারে।
লুইস আন্তোলান ক্যানো

4
@ স্মান 865 মিথ্যা ইতিবাচক: /opt/gnome-beta,, /home/bob/opt/gnome...
গিলস'স-অশুভ হওয়া বন্ধ করুন '

কাজের ক্ষেত্রে নয়: grep -w /usr/local -o <<< /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games------/usr/local /usr/local /usr/local
পাবউক

0

নির্বাচন করার জন্য /opt/gnomeঅ শব্দ অক্ষর দ্বারা বেষ্টিত (নতুন লাইন, :, /, ইত্যাদি) এই এক চেষ্টা:

grep '\B/opt/gnome'

0

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

বেসিক রেজেক্স সহ - এবং এর সাথে grep- আপনার সর্বদা দুটি নির্ভরযোগ্য অ্যাঙ্কর থাকে - লাইনের মাথা এবং লেজ। আপনি উভয়ের সাথে লাইনটিতে এর অবস্থান নির্বিশেষে কোনও ম্যাচ অ্যাঙ্কর করতে পারেন:

grep '^\(ignore case, delimiter\)*match\(delimiter, ignore case\)*$'

grep\(grouped\)আপনার ডিলিমিটারের পরে আপনার স্পষ্ট ম্যাচটি এবং আপনার ম্যাচের লেজ থেকে একইভাবে রেখার লেজ পর্যন্ত লাইনটির মাথা থেকে স্যুপ এক্সপ্রেসনের অনেকগুলি ঘটনার মুখোমুখি হবে। আপনার স্পষ্ট ম্যাচ মিলেছে করা না থাকলে স্পষ্টভাবে এটা ব্যর্থ এবং কিছুই প্রিন্ট করবে।

এবং তাই আপনি উদাহরণস্বরূপ:

grep '^\(.*:\)*/opt/gnome\(:.*\)*$'

নিজের জন্য দেখুন:

grep '^\(.*:\)*/opt/gnome\(:.*\)*$
' <<\INPUT
/opt/gnome-beta
/opt/gnome
/home/bob/opt/gnome
:/opt/gnome:
/home/bob/opt/gnome:/opt/gnome:/opt/gnome-beta
/opt-gnome-beta
/opt/gnomenot::::/opt/gnome
INPUT

আউটপুট

/opt/gnome
:/opt/gnome:
/home/bob/opt/gnome:/opt/gnome:/opt/gnome-beta
/opt/gnomenot::::/opt/gnome

0

আপনি একটি প্রান্তের কেসটি লক্ষ্য করেছেন ... আপনি এটির এটিকে জোর করে জালিয়াতি এড়াতে পারেন: লাইনের শুরুতে:

 echo ":$PATH" | grep ":/opt/gnome"

বা যদি পথটি যথাযথ হয় তবে এটি আবদ্ধ হওয়ার জন্য এটি শেষে একটি যুক্ত করুন:

 echo ":${PATH}:" | grep ":/opt/gnome:"
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.