Awk / প্যাটার্ন / {মুদ্রণ "পাঠ্য"} / প্যাটার্ন / {মুদ্রণ ""} ব্যবহার করার সময় কোনও ELSE প্যাটার্ন আছে?


22

ধরা যাক আমার কাছে টেক্সট ফাইল রয়েছে:

R1 12 324 3453 36 457 4 7 8
R2 34 2342 2525 25 25 26 26 2 2
R3 23 2342 32 52 54 543 643 63
R4 25 234 2342 4 234242

আমি awkএই লাইনগুলি আলাদাভাবে প্রক্রিয়া করতে ব্যবহার করতে চাই, পছন্দ করি

awk '/R1/ { print "=>" $0} /R2/ { print "*" $0} '

এবং আমি বাকী সমস্ত রেখাগুলি যেমন মুদ্রণ করতে চাই (আমি ইতিমধ্যে প্রক্রিয়া করা লাইনগুলির সদৃশ না করে), মূলত /ELSE/ { print $0}আমার awkলাইনের শেষে আমার একটি দরকার ।

সেখানে কি এমন জিনিস আছে?

উত্তর:


27

সরলীকৃত পদ্ধতির সাথে awk

awk '/R1/ {print "=>" $0;next} /R2/{print "*" $0;next} 1' text.file

[jaypal:~/Temp] cat text.file 
R1 12 324 3453 36 457 4 7 8
R2 34 2342 2525 25 25 26 26 2 2
R3 23 2342 32 52 54 543 643 63
R4 25 234 2342 4 234242

[jaypal:~/Temp] awk '/R1/ { print "=>" $0;next} /R2/{print "*" $0;next}1' text.file
=>R1 12 324 3453 36 457 4 7 8
*R2 34 2342 2525 25 25 26 26 2 2
R3 23 2342 32 52 54 543 643 63
R4 25 234 2342 4 234242
[jaypal:~/Temp] 

প্যাটার্ন ব্রেক অ্যাকশন} বিবৃতি:

  • /R1/ { print "=>" $0;next}: এর অর্থ /R1/মুদ্রণের ক্রিয়াযুক্ত লাইনগুলি =>সম্পন্ন হবে। nextএর অর্থ হ'ল বাকী বাকী বিবৃতি উপেক্ষা করা হবে এবং পরের লাইনে নজর দেওয়া হবে।

  • /R2/{print "*" $0;next}: এর অর্থ pattern /R2/মুদ্রণের ক্রিয়াটির সাথে মিলিত লাইনগুলি *সম্পন্ন হবে। awkপ্রসেসিং শুরু হয়ে গেলে , প্রথম pattern {action}বিবৃতিটিকে অগ্রাহ্য করা pattern /R1/হবে কারণ লাইন থাকার কারণে এটি সত্য হবে না /R2/। সুতরাং দ্বিতীয় pattern {action}বিবৃতি লাইনে করা হবে। nextআবার এর অর্থ হ'ল আমরা আর কোনও প্রসেসিং চাই না এবং awkযথাযথভাবে পরবর্তী লাইনে যাব।

  • 1সমস্ত লাইন মুদ্রণ। যখন কেবল কোনও শর্ত সরবরাহ করা হয় না {action}, ব্যবহারের জন্য বিশ্রী ডিফল্ট {print}। এখানে শর্তটি 1যা সত্য হিসাবে ব্যাখ্যা করা হয়েছে, তাই এটি সর্বদা সফল হয়। যদি আমরা এই জায়গায় পৌঁছে যাই, কারণ এটি প্রথম এবং দ্বিতীয় pattern {action}বিবৃতি উপেক্ষা করা হয়েছিল বা পাশ করে দেওয়া হয়েছিল (লাইনগুলিতে নেই /R1/এবং এতে রয়েছে /R2/), তাই বাকী রেখাগুলির জন্য ডিফল্ট মুদ্রণ ক্রিয়াটি করা হবে।


পোস্ট করা সমস্ত সমাধানের মধ্যে প্রান্তিকভাবে দ্রুততম রান চালানো বলে মনে হচ্ছে।
ক্রিস ডাউন

1
আমি নিশ্চিত নই যে সিনট্যাকটিক চিনি এখানে সঠিক শব্দটি ... এটি কেবল বাক্য গঠন।
ড্যানিয়েল হার্শকোভিচ

7

awkএটি যখন শর্তযুক্ত হয় তখন সাধারণ সন্দেহভাজনদের প্রয়োগ করে। আপনি যে কাজের জন্য ম্যাচটি করতে চাইছেন তার printfপরিবর্তে ব্যবহার করা ভাল ধারণা print

awk '{ if (/^R1/) { printf("=> %s\n", $0) } else if (/^R2/) { printf("* %s\n", $0) } else { print $0 } }'

আপনার আসলে এর প্রয়োজন নেই if-then-else
জয়পাল সিং

1
যদিও এটি পুরোপুরি ভালভাবে কাজ করে, এটি মুশকিল নয়। ন্যায়বিচারের ব্যবহারটি nextঅ্যাডক প্রোগ্রামিংয়ের একটি গুরুত্বপূর্ণ সরঞ্জাম।
dmckee

2
আমি printfএখানে ব্যবহারের বিন্দুটি বুঝতে পারি না । এর একমাত্র সুবিধা (যদি না আপনি কনটেনটেশনের চেয়ে ফ্যানসিয়ার ফর্ম্যাটিং করছেন) তবে এটি কোনও নতুন লাইন যুক্ত করবে না, যা এখানে প্রাসঙ্গিক নয়।
গিলস 'দুষ্ট হওয়া বন্ধ করুন'

1
এটি একটি পাল্টা এবং অবাক করা ফলাফল। অযত্নহীন printকেবলমাত্র আউটপুট দিতে হয় $0যেখানে printfএকটি ফর্ম্যাট স্ট্রিংকে পার্স করতে হয়।
jw013

5

ক্রিস ডাউন ইতিমধ্যে দেখিয়েছে যে কীভাবে আপনি একটি ব্লকের স্পষ্টত 'if' বিবৃতি ব্যবহার করে regexps জন্য অন্য কোনও পেতে পারেন। আপনি কিছু অন্যান্য উপায়েও একই প্রভাব পেতে পারেন, যদিও তার সমাধান সম্ভবত আরও ভাল।

একটি তৃতীয় রেজেক্স লিখতে হবে যা কেবল অন্যদের সাথে মেলে না এমন পাঠ্যের সাথে মিলবে, আপনার ক্ষেত্রে এটি দেখতে এরকম কিছু দেখবে:

awk '/^R1/ { print "=>" $0}
     /^R2/ { print "*" $0}
     /^[^R]/ || /^R[^12]/ { print $0 } '

দ্রষ্টব্য, এটি নোঙ্গর করা regexps ব্যবহার করে - রেজেক্সপসের শুরুতে a কেবল একটি লাইনের শুরুতে মিলবে - আপনার মূল নিদর্শনগুলি এটি করে নি, যা মিলাকে কিছুটা কমিয়ে দেয় কারণ এটি একটি লাইনে সমস্ত অক্ষর চেক করবে না পরের লাইন অবধি স্কিপিং তৃতীয় ("অন্য") কেস এমন একটি রেখার সাথে মিলবে যা কিছু অক্ষর দিয়ে শুরু হয় যা 'আর' নয় ([^ আরআর]) বা এটি শুরু হয় 'আর' এর পরে একটি অক্ষর যা '1' বা 'নয়' 2 '(আর [^ 12])। Different এর দুটি পৃথক অর্থ কিছুটা বিভ্রান্তিকর, তবে সেই ভুলটি অনেক আগে হয়েছিল এবং শীঘ্রই কোনও পরিবর্তন করা হবে না।

পরিপূরক রেজেক্সপগুলি ব্যবহার করার জন্য, তাদের সত্যিকারের অ্যাঙ্কর করা দরকার, অন্যথায় [] R] যেমন এটি অনুসরণ করা 1 টির সাথে মিলবে। আপনার মতো খুব সাধারণ রেইগেক্সপসের জন্য, এই পদ্ধতির ব্যবহার কার্যকর হতে পারে, তবে রেজিেক্সপস আরও জটিল হওয়ার সাথে সাথে, এই পদ্ধতির ব্যবস্থা করা যায় না। পরিবর্তে, আপনি প্রতিটি লাইনের জন্য রাষ্ট্রের ভেরিয়েবলগুলি ব্যবহার করতে পারেন:

awk '{ handled = 0 }
     /^R1/ { print "=>" $0; handled = 1}
     /^R2/ { print "*" $0; handled = 1}
     { if (!handled) print $0 } '

এই সেটগুলি প্রতিটি নতুন লাইনের জন্য শূন্যে পরিচালিত হয়, তারপরে 1 এ এটি দুটি রিজেক্সপগুলির মধ্যে দুটির সাথে মিলে গেলে এবং শেষ পর্যন্ত যদি এটি শূন্য হয় তবে মুদ্রণ $ 0 চালায়।


এটি লক্ষ করা উচিত যে বড় ফাইলগুলিতে উভয়ই কন্ডিশনাল ব্যবহারের চেয়ে কম দক্ষ ( এখানে দেখানো হয়েছে )। rfileপ্রশ্নকারীর ডেটাসেটের কেবল 10000 লাইনের পুনরাবৃত্তি।
ক্রিস ডাউন

4
if (!handled)ইশ! nextঅন্যান্য ক্রিয়া বিবেচনা বন্ধ করতে ব্যবহার করুন ।
dmckee

+1 এর জন্য if (!handled)। সাধারণ, নমনীয়, পুনরায় ব্যবহারযোগ্য সমাধানগুলি ভাল। যদি এই প্রশ্নটি পরবর্তী ব্যক্তি মুদ্রণের পরে আরও প্রসেসিং করতে চান তবে কী হবে? উত্তরগুলি nextসমর্থন করে না।
স্কট
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.