স্কার্প-মোড অজানা?


16

সরঞ্জামের মত sed, awkবা perl -nতাদের ইনপুট এক প্রক্রিয়া রেকর্ড একটি সময়ে, রেকর্ড হচ্ছে লাইন ডিফল্টরূপে।

কেউ কেউ মত awkদিয়ে RS, গনুহ sedসঙ্গে -zবা perlসঙ্গে -0oooএকটি ভিন্ন রেকর্ড বিভাজক নির্বাচন করে রেকর্ড ধরণ পরিবর্তন করতে পারেন।

perl -nপুরো ইনপুটটিকে (একাধিক ফাইল পাস করার সময় প্রতিটি স্বতন্ত্র ফাইল) বিকল্পের সাথে একক রেকর্ড তৈরি করতে পারে -0777(বা -0তারপরে 0377, 7 the7 এর চেয়ে বেশি কোনও অষ্টাল সংখ্যার পরে নীতিগত)। এগুলিকে তারা স্লার্প মোড বলে

অনুরূপ কিছু দিয়ে করা যাবে awk'র RSবা অন্য কোন প্রক্রিয়া? যেখানে awkপ্রতিটি ফাইলের প্রতিটি লাইনের বিপরীতে প্রতিটি ফাইল সামগ্রীতে সামগ্রিক প্রক্রিয়া করে ?

উত্তর:


15

আপনি কিনা তার উপর নির্ভর করে বিভিন্ন পন্থা গ্রহণ করতে পারেন awkএকইরূপে RS(সনাতন মত একটি একক অক্ষর হিসেবে awkনা বাস্তবায়নের) অথবা একটি রেগুলার এক্সপ্রেশন হিসাবে (মত gawkবা mawkনা)। খালি ফাইলগুলি awkএড়িয়ে যাওয়ার প্রবণতা হিসাবে বিবেচিত হওয়াও কঠিন ।

gawk, mawkবা অন্যান্য awkবাস্তবায়ন যেখানে RSএকটি রেজিপেক্স হতে পারে।

এই বাস্তবায়নগুলিতে (কারণ mawk, সাবধান! কিছু থিমসডিকির দ্বারা পরিচালিত আধুনিক সংস্করণের পরিবর্তে দেবিয়ান জাতীয় কিছু ওএসের পাঠানো পুরানো সংস্করণে ) যদি RSএকটি একক অক্ষর থাকে তবে রেকর্ড বিভাজকটি সেই চরিত্রটি থাকে বা খালি awkহলে অনুচ্ছেদে মোডে প্রবেশ করে RS, বা RSঅন্যথায় একটি নিয়মিত অভিব্যক্তি হিসাবে আচরণ করে ।

এর সমাধানটি হ'ল একটি নিয়মিত ভাব প্রকাশ করা যা সম্ভবত মেলে না। কিছু মনে x^বা $x( xশুরু করার আগে, বা শেষের পরে) মনে আসে। তবে কিছু (বিশেষত সাথে gawk) অন্যের চেয়ে ব্যয়বহুল। এখনও অবধি, আমি খুঁজে পেয়েছি যে ^$এটি সবচেয়ে দক্ষ একটি। এটি কেবল একটি খালি ইনপুটটিতে মিলতে পারে তবে এর বিরুদ্ধে মিলার মতো কিছুই থাকবে না।

সুতরাং আমরা করতে পারি:

awk -v RS='^$' '{printf "%s: <%s>\n", FILENAME, $0}' file1 file2...

যদিও একটি সতর্কতাই হ'ল এটি খালি ফাইলগুলি এড়িয়ে যায় (বিপরীতে perl -0777 -n)। পরিবর্তে awkএকটি ENDFILEবিবৃতিতে কোডটি রেখে জিএনইউ দিয়ে সম্বোধন করা যেতে পারে । তবে আমাদের $0একটি বিগইনফাইলে বিবৃতিতে পুনরায় সেট করতে হবে কারণ এটি খালি ফাইল প্রক্রিয়া করার পরে পুনরায় সেট করা হবে না:

gawk -v RS='^$' '
   BEGINFILE{$0 = ""}
   ENDFILE{printf "%s: <%s>\n", FILENAME, $0}' file1 file2...

traditional awkতিহ্যবাহী বাস্তবায়ন, পসিক্সawk

এর মধ্যে RSকেবল একটি চরিত্র, তাদের BEGINFILE/ নেই ENDFILE, তাদের RTচলক নেই, তারা সাধারণত NUL চরিত্রটি প্রক্রিয়া করতে পারে না।

আপনি ভেবেছিলেন যে RS='\0'ব্যবহারটি তখন কার্যকর হতে পারে যেহেতু তারা ইনপুট প্রক্রিয়া করতে পারে না যার মধ্যে NUL বাইট রয়েছে, তবে না, RS='\0'traditional তিহ্যবাহী বাস্তবায়নের ক্ষেত্রে যেমন RS=অনুচ্ছেদ মোড is

একটি সমাধান হতে পারে এমন একটি অক্ষর ব্যবহার করা যা ইনপুটটির মতো সন্ধানের সম্ভাবনা নেই \1। মাল্টিবাইট চরিত্রের লোকেলগুলিতে, আপনি এটিকে বাইট-সিকোয়েন্সগুলি তৈরি করতে পারেন $'\U10FFFE'যা ইউটিএফ -8 লোকেলের মতো বরাদ্দ না দেওয়া বা অ-অক্ষরগুলি তৈরি করে এমন অক্ষর গঠন করে যা ঘটে যাওয়ার খুব সম্ভবত সম্ভাবনা নেই । যদিও সত্যই নির্বোধ নয় এবং খালি ফাইলগুলি নিয়ে আপনারও সমস্যা রয়েছে।

আর একটি সমাধান হ'ল সম্পূর্ণ ইনপুটটি একটি ভেরিয়েবলের মধ্যে সঞ্চয় করা এবং শেষে স্ট্যান্ড স্টেটমেন্টে প্রক্রিয়া করা। এর অর্থ আপনি একবারে কেবল একটি ফাইল প্রক্রিয়া করতে পারেন যদিও:

awk '{content = content $0 RS}
     END{$0 = content
       printf "%s: <%s>\n", FILENAME, $0
     }' file

এটি এর সমতুল্য sed:

sed '
  :1
  $!{
   N;b1
  }
  ...' file1

এই পদ্ধতির সাথে আরেকটি সমস্যা হ'ল যদি ফাইলটি একটি নতুন লাইনের চরিত্রের মধ্যে না শেষ হয় (এবং খালি ছিল না) তবে একটি এখনও নির্বিচারে $0শেষে যুক্ত করা হয়েছে (সহ gawk, আপনি এর RTপরিবর্তে এটি ব্যবহার করে কাজ RSকরবেন উপরের কোড)। একটি সুবিধা হ'ল আপনার NR/ / তে ফাইলটিতে রেখার সংখ্যার রেকর্ড রয়েছে FNR


শেষ অংশ হিসাবে ("যদি ফাইলটি কোনও নতুন লাইনের অক্ষরে শেষ না হয় (এবং খালি না থাকে) তবে একটি এখনও নির্বিচারে $ 0 এ যুক্ত করা হয়েছে"): পাঠ্য ফাইলগুলির জন্য, তাদের একটি শেষ হওয়ার কথা রয়েছে নতুন লাইন. vi উদাহরণস্বরূপ একটি যুক্ত করে, এবং আপনি যখন সংরক্ষণ করেন তখন ফাইলটি পরিবর্তন করুন। একটি সমাপ্তি নিউলাইন না থাকা কিছু কমান্ডকে শেষ "লাইন" (উদা: ডাব্লুসিটি) বাতিল করে দেয় তবে অন্যরা এখনও শেষ লাইনটি 'দেখুন' ... ymmv। তাই আপনার সমাধানটি বৈধ, তবে, যদি আপনি পাঠ্য ফাইলগুলি চিকিত্সা করার কথা ভাবা হয় (যা সম্ভবত এটি, যেমন টেক্সট প্রসেসিংয়ের জন্য অ্যাজক ভাল তবে বাইনারিগুলির পক্ষে খুব ভাল নয় ^^)
অলিভিয়ার ডুলাক

1
সমস্ত কিছু স্লাপ করার চেষ্টা কিছু সীমাবদ্ধতার মধ্যে পড়তে পারে ... traditionতিহ্যবাহী আঁতকে স্পষ্টতই একটি লাইনে 99 টি ক্ষেত্রের সীমা ছিল (আছে?) ... সুতরাং সেই সীমাটি এড়াতে আপনার আলাদা আলাদা FS ব্যবহারের প্রয়োজনও হতে পারে, তবে আপনি একটি লাইনের মোট দৈর্ঘ্য (বা পুরো জিনিসটি, যদি আপনি এটি সমস্ত এক লাইনে রাখার ব্যবস্থা করেন) তবে কত দীর্ঘ হতে পারে তারও সীমা রয়েছে?
অলিভিয়ার ডুলাক

অবশেষে: একটি (নিরীহ ...) হ্যাক প্রথম ফাইলটিকে পুরো বিশ্লেষণ করতে পারে এবং সেখানে যে চর নেই tr '\n' 'thatchar' সেটিকে অনুসন্ধান করতে পারে , তারপরে ফাইলটিকে বিশৃঙ্খলায় প্রেরণের আগে ফাইল এবং tr 'thatchar' \n'আউটপুট? (আপনার উপরে এখনও উল্লেখ করা মতো আপনার নতুন লাইনের সংযোজন দরকার হতে পারে, যেমন আপনার ইনপুট ফাইলে একটি টার্মিনেটিং নিউলাইন রয়েছে: { tr '\n' 'missingchar' < thefile ; printf "\n" ;} | awk ..... | { tr 'missingchar' '\n' }(তবে এটি শেষের দিকে '\ n' যুক্ত করে, যাতে আপনাকে মুক্তি দেওয়ার দরকার হতে পারে ... সম্ভবত চূড়ান্ত ট্রির আগে একটি সেড যুক্ত করা? যদি সে টিআর নতুন লাইনগুলি বন্ধ না করেই ফাইলগুলি গ্রহণ করে ...)
অলিভিয়ার ডুলাক

@ অলিভিয়ারডুলাক, ক্ষেত্রের সংখ্যার সীমা কেবল তখনই আঘাত হানবে যদি আমরা এনএফ বা কোনও ক্ষেত্র অ্যাক্সেস করতে পারি। awkআমরা যদি না করি তবে বিভাজন করে না। যে বলেন না, এমনকি /bin/awkসোলারিস 9 (1970 এর awk উপর ভিত্তি করে), যে সীমাবদ্ধতা ছিল তাই আমি করছি না নিশ্চিত যে সম্ভব যে না (এখনও যেমন SVR4 এর oawk 99 এবং nawk 199 সীমা ছিল খুঁজে পেতে পারেন, তাই এটা সম্ভবত এই সীমাটি উত্তোলন সূর্যের দ্বারা যুক্ত করা হয়েছিল এবং এটি অন্য এসভিআর 4 ভিত্তিক জাদাগুলিতে পাওয়া যায় না, আপনি এআইএক্স-এ পরীক্ষা করতে পারেন?)।
স্টাফেন চেজেলাস
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.