গ্রেপ কমান্ডের ফলে প্রাপ্ত প্রতিটি লাইনকে কীভাবে প্রক্রিয়া করা যায়


152

গ্রাইপ কমান্ডটি চালানোর পরে একটি ফাইল থেকে আমার বেশ কয়েকটি লাইন পুনরুদ্ধার করা হয়েছে:

var=`grep xyz abc.txt`

ধরা যাক আমি 10 টি লাইন পেয়েছি যার ফলে xyz রয়েছে y

গ্রেপ কমান্ডের ফলস্বরূপ আমি যে প্রতিটি লাইন পেয়েছি তা এখনই প্রক্রিয়া করা দরকার। আমি এর জন্য কীভাবে এগিয়ে যাব?


6
এখানে উত্তরগুলির মধ্যে কোনওটিতে grep -oএই ধরণের জিনিসটির শক্তির উল্লেখ নেই । -oপতাকা ফেরত দিতে হবে শুধুমাত্র প্রতি আউটপুট লাইন এক ম্যাচ সঙ্গে, পাঠ্য ম্যাচ। (এটি সম্পূর্ণ নয়, সুতরাং echo aaa |grep 'a*'কেবল আপনাকে "আআ" দেয় এবং তিনটি আংশিক ম্যাচ "", "এ" এবং "

উত্তর:


269

একটি সহজ উপায় হ'ল আউটপুটটি ভেরিয়েবলের মধ্যে সঞ্চয় না করা, তবে কিছুক্ষণ / পঠন লুপের সাহায্যে সরাসরি এটির পুনরাবৃত্তি।

কিছুটা এইরকম:

grep xyz abc.txt | while read -r line ; do
    echo "Processing $line"
    # your code goes here
done

আপনি ঠিক কী পরে আছেন তার উপর নির্ভর করে এই স্কিমের বিভিন্নতা রয়েছে।

যদি আপনাকে লুপের ভিতরে ভেরিয়েবলগুলি পরিবর্তন করতে হয় (এবং তার পরিবর্তে এটির বাইরে দৃশ্যমান থাকে), আপনি ফেডোরকিয়ার উত্তরে বর্ণিত প্রক্রিয়া বিকল্প ব্যবহার করতে পারেন :

while read -r line ; do
    echo "Processing $line"
    # your code goes here
done < <(grep xyz abc.txt)

xyz এর সাথে কোন লাইন না থাকলে?
এক্সওয়াইজেড_লিনাক্স

তারপরে কিছুই হয় না, লুপটি চালানো হয় না।
মাদুর

13
এই পদ্ধতির সমস্যাটি হ'ল (পাইপের কারণে) লুপের ভিতরে থাকা সমস্ত কিছুই একটি সাবশেলে থাকে, সুতরাং লুপের সময় লুপের বাইরে সংজ্ঞায়িত ভেরিয়েবলগুলি সেট করা তাদের মানগুলি লুপের পরে উপলব্ধ করে না!
ডেভিড ডরিয়া

3
@ ডেভিড: আপনার উদ্বেগের সমাধানের জন্য একটি বিকল্প সরবরাহ করেছে। (ফেডোরকিও এরই মধ্যে এটি সম্বোধন করেছে))
Mat

কমান্ড যার গত আউটপুট লাইন একটি newline দিয়ে শেষ করা হয় না, যদি আপনি প্রয়োজন চাই: while read p || [[ -n $p ]]; do ...(থেকে ধার stackoverflow.com/questions/1521462/... )
ওহদ স্নাইডার

21

আপনি নিম্নলিখিত while readলুপটি করতে পারেন , যা grepতথাকথিত প্রক্রিয়া প্রতিস্থাপন ব্যবহার করে কমান্ডের ফলাফল দ্বারা খাওয়ানো হবে :

while IFS= read -r result
do
    #whatever with value $result
done < <(grep "xyz" abc.txt)

এইভাবে, আপনাকে ফলটি কোনও চলকতে সঞ্চয় করতে হবে না, তবে লুপটিতে সরাসরি তার "আউটজেক্ট" করতে হবে।


বাশএফএকিউ / 001 এর প্রস্তাবনাগুলি অনুসারে IFS=এবং তার ব্যবহার read -rঅনুসারে নোট করুন : আমি কীভাবে কোনও ফাইল (ডেটা স্ট্রিম, ভেরিয়েবল) লাইন বাই লাইন (এবং / অথবা ক্ষেত্রের বাইরের ক্ষেত্র) পড়তে পারি? :

পড়ার জন্য -r বিকল্পটি ব্যাকস্ল্যাশ ব্যাখ্যাকে বাধা দেয় (সাধারণত ব্যাকস্ল্যাশ নিউলাইন জোড় হিসাবে ব্যবহৃত হয়, একাধিক লাইনে চালিয়ে যাওয়ার জন্য বা ডিলিমিটরগুলি থেকে বাঁচতে)। এই বিকল্পটি ব্যতীত ইনপুটটিতে থাকা কোনও অনস্কেপড ব্যাকস্ল্যাশগুলি ফেলে দেওয়া হবে। আপনার প্রায়শই পড়ার সাথে -r বিকল্পটি ব্যবহার করা উচিত।

উপরের দৃশ্যে আইএফএস = শীর্ষস্থানীয় এবং পিছনের সাদা স্থানের ছাঁটাই প্রতিরোধ করে। আপনি যদি এই প্রভাবটি চান তবে এটি সরান।

প্রক্রিয়া প্রতিস্থাপন সম্পর্কিত, এটি ব্যাশ হ্যাকার্স পৃষ্ঠায় ব্যাখ্যা করা হয়েছে :

প্রক্রিয়া প্রতিস্থাপন পুনঃনির্দেশের একটি ফর্ম যেখানে কোনও প্রক্রিয়ার ইনপুট বা আউটপুট (কমান্ডের কিছু ক্রম) অস্থায়ী ফাইল হিসাবে উপস্থিত হয়।


ঠিক আছে, আমি forসংস্করণটি স্ট্রাইক করেছি । স্ট্যাকওভারফ্লো . com/ a/ 14588210/1983854"${$(grep xyz abc.txt)[@]}" হিসাবে যেমন একটি লুপ করার চেষ্টা করেছিল কিন্তু পারেনি। সুতরাং আমি শুধু প্রথম সংস্করণ ছেড়ে।
ফেডরকিই 'এসও ক্ষতিগ্রস্থ হওয়া বন্ধ করুন'

1
আপনি কমান্ড প্রতিস্থাপনে প্যারামিটার সম্প্রসারণ প্রয়োগ করতে পারবেন না (যদি আপনি ব্যবহার না করেন zsh, যেখানে এই ধরণের বাসা সম্ভবত কাজ করে)।
চিপনার

এই আইডিয়ামটির সাথে একটি সম্ভাব্য সমস্যা হ'ল লুপের অভ্যন্তরীণ কিছু যদি স্ট্যান্ডার্ড ইনপুট থেকে পড়ার চেষ্টা করে তবে এটি ফাইলের অংশ পাবে। এই সম্ভাবনাটি এড়াতে, আমি স্টিডিনের পরিবর্তে ফাইলটি বর্ণনাকারী 3 এর মাধ্যমে ফাইলটি প্রেরণ করতে চাই। স্রেফ ব্যবহার while IFS= read -r result <&3এবংdone 3< <(grep ...
গর্ডন ডেভিসন

8

আমি এখানে গ্রেপ + এর পরিবর্তে আরও কিছু ব্যবহার করার পরামর্শ দেব।

awk '$0~/xyz/{ //your code goes here}' abc.txt


1
আপনি সম্পূর্ণ পাওয়া রেখাটি কীভাবে উল্লেখ করবেন //your code goes here?
ব্যবহারকারী 857990

2
@ user857990 পুরো লাইনটি এডাব্লুকেতে $ 0 হিসাবে উপস্থাপিত হয়।
জুলিয়েন গ্রেনিয়ার

2

- লাইন-বাফার্ড গ্রেপ বিকল্পের সাথে কোনও পুনরাবৃত্তি ছাড়াই:

your_command | grep --line-buffered "your search"

রিয়েল লাইফ উদাহরণস্বরূপ সিমফনি পিএইচপি ফ্রেমওয়ার্ক রাউটার ডিবাগ কমান্ড আউটপুট, সমস্ত "এপিআই" সম্পর্কিত রুটগুলি গ্রেপ করতে:

php bin/console d:r | grep --line-buffered "api"

যদি আপনার_কম্যান্ড দীর্ঘস্থায়ী হয় তবে একমাত্র সমাধানটি কার্যকর হয় (যেমন tail -f some.log, আমার ক্ষেত্রে) ...
ইজকাটা

0

প্রায়শই প্রক্রিয়াকরণের ক্রমের বিষয়টি বিবেচনা করে না। জিএনইউ সমান্তরাল এই পরিস্থিতির জন্য তৈরি:

grep xyz abc.txt | parallel echo do stuff to {}

আপনি যদি প্রক্রিয়াজাতকরণ আরও পছন্দ হয়:

grep xyz abc.txt | myprogram_reading_from_stdin

এবং myprogramধীরে ধীরে আপনি চালাতে পারেন:

grep xyz abc.txt | parallel --pipe myprogram_reading_from_stdin

0

কিছুক্ষণ / পঠন লুপের সাহায্যে গ্রেপের ফলাফলগুলি পরিমাপ করুন। ভালো লেগেছে:

grep pattern filename.txt | while read -r line ; do
    echo "Matched Line:  $line"
    # your code goes here
done

0

ওয়ান-লাইনার সন্ধানকারীদের জন্য:

grep xyz abc.txt | while read -r line; do echo "Processing $line"; done
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.