পাঠ্যকে প্রক্রিয়াজাত করতে শেল লুপ ব্যবহার করা খারাপ অভ্যাস হিসাবে বিবেচনা করা হয় কেন?


196

পোসেক্স শেলগুলিতে পাঠ্যকে সাধারণত খারাপ অনুশীলন হিসাবে বিবেচনা করার জন্য কিছুক্ষণ লুপ ব্যবহার করা হয় ?

স্টাফেন চ্যাজেলাস যেমন উল্লেখ করেছেন , শেল লুপ ব্যবহার না করার কয়েকটি কারণ হ'ল ধারণা , বিশ্বাসযোগ্যতা , স্বচ্ছলতা , কর্মক্ষমতা এবং সুরক্ষা

এই উত্তরটি নির্ভরযোগ্যতা এবং স্বচ্ছতার দিকগুলি ব্যাখ্যা করে :

while IFS= read -r line <&3; do
  printf '%s\n' "$line"
done 3< "$InputFile"

জন্য কর্মক্ষমতা , whileলুপ এবং পঠিত এইসা ধীর যখন একটি ফাইল বা একটি নল থেকে পড়া হয়, কারণ পঠিত শেল বিল্ট-ইন একটি সময়ে এক চরিত্র পড়ে।

ধারণা এবং সুরক্ষা দিক সম্পর্কে কীভাবে ?



1
অন্তর্নির্মিত পঠিত শেলটি একবারে একটি অক্ষর পড়ে না, এটি একবারে একটি লাইন পড়ে reads wiki.bash-hackers.org/commands/builtin/read
A.Danischewski

@ এ ড্যানিশচেউস্কি: এটি আপনার শেলের উপর নির্ভর করে। ইন bash, এটি একবারে একটি বাফার আকার পড়ে, dashউদাহরণস্বরূপ চেষ্টা করুন । এছাড়াও unix.stackexchange.com/q/209123/38906
cuonglm

উত্তর:


256

হ্যাঁ, আমরা বেশ কয়েকটি জিনিস দেখতে পাই:

while read line; do
  echo $line | cut -c3
done

বা তার থেকেও খারাপ:

for line in `cat file`; do
  foo=`echo $line | awk '{print $2}'`
  echo whatever $foo
done

(হাসবেন না, আমি তাদের অনেকগুলি দেখেছি)।

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

ধারণার দিক থেকে

সি বা অন্যান্য ভাষায়, বিল্ডিং ব্লকগুলি কম্পিউটারের নির্দেশাবলীর ঠিক এক স্তরের উপরে। আপনি আপনার প্রসেসরকে বলবেন কী করবেন এবং তারপরে আর কি করবেন। আপনি নিজের প্রসেসরটি হাত দিয়ে নিয়ে যান এবং মাইক্রো ম্যানেজ করেন: আপনি সেই ফাইলটি খোলেন, আপনি পড়েন যে অনেকগুলি বাইট, আপনি এটি করেন, আপনি এটি দিয়ে এটি করেন।

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

ইউনিক্স যে দুর্দান্ত জিনিসগুলির সূচনা করেছিল তার মধ্যে একটি হ'ল পাইপ এবং সেগুলি ডিফল্ট স্টিডিন / স্টিডআউট / স্টডার স্ট্রিম যা সমস্ত কমান্ড ডিফল্টরূপে হ্যান্ডেল করে।

৪৫ বছরে, আমরা কমান্ডের শক্তিকে বাড়িয়ে তুলতে এবং কোনও কার্যক্রমে তাদের সহযোগিতা করার জন্য সেই API এর চেয়ে ভাল পাইনি। লোকেরা আজও শেল ব্যবহার করছে বলে সম্ভবত এটিই প্রধান কারণ।

আপনার কাছে একটি কাটিয়া সরঞ্জাম এবং প্রতিবর্ণী সরঞ্জাম পাওয়া গেছে এবং আপনি কেবল এটি করতে পারেন:

cut -c4-5 < in | tr a b > out

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

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

চালনা cutরান্নাঘরের ড্রয়ার খোলার মতো, ছুরিটি নিন, এটি ব্যবহার করুন, ধুয়ে ফেলুন, শুকিয়ে নিন, আবার ড্রয়ারে রেখে দিন। যখন তুমি কর:

while read line; do
  echo $line | cut -c3
done < file

এটি ফাইলের প্রতিটি লাইনের মতো, readরান্নাঘরের ড্রয়ার থেকে সরঞ্জাম পেয়ে যাওয়া (খুব আনাড়ি কারণ এটি এর জন্য ডিজাইন করা হয়নি ), একটি লাইন পড়ুন, আপনার পড়ার সরঞ্জামটি ধুয়ে ফেলুন, আবার ড্রয়ারে রেখে দিন। তারপরে echoএবং cutসরঞ্জামটির জন্য একটি সভা নির্ধারণ করুন, এটিকে ড্রয়ার থেকে এনে ডেকে আনুন, তাদের ধুয়ে ফেলুন, শুকিয়ে নিন, আবার ড্রয়ারে রেখে দিন।

সেগুলির কয়েকটি ( readএবং echo) বেশিরভাগ শেলের মধ্যে নির্মিত, তবে যেহেতু এখানে খুব কমই একটি পার্থক্য তৈরি হয়েছে echoএবং cutএখনও পৃথক প্রক্রিয়াতে চালানো দরকার।

এটি পেঁয়াজ কাটার মতো তবে আপনার ছুরি ধুয়ে প্রতিটি ফালিগুলির মধ্যে রান্নাঘরের ড্রয়ারে রেখে দিন।

এখানে স্পষ্ট উপায় হ'ল cutড্রয়ার থেকে আপনার সরঞ্জামটি পাওয়া, আপনার পুরো পেঁয়াজ কেটে টুকরো টুকরো করে পুরো কাজটি শেষ করার পরে ড্রয়ারে এটি আবার রেখে দেওয়া।

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

ব্রুস এর সূক্ষ্ম উত্তরে আরও পড়া । শেলগুলিতে নিম্ন-স্তরের পাঠ্য প্রক্রিয়াজাতকরণ অভ্যন্তরীণ সরঞ্জামগুলি (সম্ভবত এটি ব্যতীত zsh) সীমাবদ্ধ, জটিল এবং সাধারণ পাঠ্য প্রক্রিয়াকরণের জন্য সাধারণত ফিট হয় না।

কর্মক্ষমতা

যেমনটি আগেই বলা হয়েছিল, একটি কমান্ড চালাতে একটি ব্যয় হয়। যদি এই কমান্ডটি অন্তর্নির্মিত না হয় তবে একটি বিশাল ব্যয়, তবে সেগুলি বিল্ট ইন হলেও, ব্যয়টি বড়।

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

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

সংশ্লিষ্ট এমনকি builtin শেল ইউটিলিটি ( read, echo, printf) যে করতে পারবেন না। readএকটি লাইন পড়া বোঝানো হয়। এটি যদি নতুন লাইনের চরিত্রটি পড়ে যায় তবে এর অর্থ হল আপনি চালিত পরবর্তী আদেশটি এটি মিস করবে। সুতরাং readএকবারে ইনপুটটি একটি বাইটটি পড়তে হবে (কিছু প্রয়োগের একটি অপ্টিমাইজেশন থাকে যদি ইনপুটটি নিয়মিত ফাইল থাকে যাতে তারা খণ্ডগুলি পড়ে এবং ফিরে চাওয়া হয় তবে এটি কেবল নিয়মিত ফাইলগুলির জন্য কাজ করে এবং bashউদাহরণস্বরূপ কেবল 128 বাইট খণ্ডগুলি পড়ে যা পাঠ্য ইউটিলিটিগুলি এর চেয়ে অনেক কম হবে)।

আউটপুট দিকে একই, echoএটির আউটপুটটি কেবল বাফার করতে পারে না, সরাসরি এটি আউটপুট দিতে হয় কারণ আপনি যে পরবর্তী কমান্ডটি চালান সে বাফারটি ভাগ করে নেবে না।

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

আমার দ্রুত পরীক্ষায় সেই while readলুপ এবং (অনুমিত) সমতুল্যের cut -c3 < fileমধ্যে আমার পরীক্ষাগুলিতে সিপিইউ সময়ের অনুপাত 40000 (অর্ধ দিনের তুলনায় এক সেকেন্ড) থাকে ratio এমনকি যদি আপনি কেবল শেল বিল্টিন ব্যবহার করেন:

while read line; do
  echo ${line:2:1}
done

(এখানে এখানে bash), এটি এখনও প্রায় 1: 600 (এক সেকেন্ড বনাম 10 মিনিট) এর কাছাকাছি।

নির্ভরযোগ্যতা / স্পষ্টতা

এই কোডটি সঠিকভাবে পাওয়া খুব কঠিন। আমি যে উদাহরণগুলি দিয়েছি তা বন্যগুলিতে প্রায়শই দেখা যায় তবে তাদের অনেকগুলি বাগ রয়েছে।

readএকটি সহজ সরঞ্জাম যা বিভিন্ন বিভিন্ন জিনিস করতে পারে। এটি ব্যবহারকারীর কাছ থেকে ইনপুট পড়তে পারে, শব্দগুলিতে বিভক্ত করে বিভিন্ন ভেরিয়েবলগুলিতে সঞ্চয় করতে পারে। read lineনেই না ইনপুট একটি লাইন পড়া, হয়তো বা এটি একটি খুব বিশেষ পদ্ধতিতে একটি লাইন পড়ে। এটি প্রকৃতপক্ষে শব্দগুলিকে ইনপুট থেকে শব্দগুলি পড়ে এবং সেই শব্দগুলি পৃথক করে $IFSএবং যেখানে ব্যাকস্ল্যাশ পৃথককারী বা নিউলাইন চরিত্রের হাত থেকে বাঁচতে ব্যবহৃত হতে পারে।

এর ইনপুটটিতে এর ডিফল্ট মান সহ $IFS:

   foo\/bar \
baz
biz

read lineসংরক্ষণ করবে "foo/bar baz"মধ্যে $line, না " foo\/bar \"হিসাবে আপনি আশা চাই।

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

IFS= read -r line

এটি খুব স্বজ্ঞাত নয়, তবে এটি এটিই মনে রাখবেন, শেলগুলি ব্যবহার করা হয়নি to

একই জন্য echoechoক্রম প্রসারিত। আপনি এলোমেলো ফাইলের বিষয়বস্তুর মতো স্বেচ্ছাচারী বিষয়বস্তুর জন্য এটি ব্যবহার করতে পারবেন না। printfপরিবর্তে এখানে আপনার প্রয়োজন ।

এবং অবশ্যই, এখানে আপনার ভেরিয়েবলের উদ্ধৃতি দেওয়া সাধারণত ভুলে যাওয়া যা প্রত্যেকের মধ্যে পড়ে। সুতরাং এটি আরও:

while IFS= read -r line; do
  printf '%s\n' "$line" | cut -c3
done < file

এখন, আরও কয়েকটি সতর্কতা:

  • ছাড়া zsh, যে অন্তত গনুহ টেক্সট ইউটিলিটি সমস্যা হতো না যদি ইনপুট NUL অক্ষর রয়েছে কাজ করে না।
  • শেষ নিউলাইনের পরে যদি ডেটা থাকে তবে তা এড়িয়ে যাবে
  • লুপের ভিতরে, স্টিডিন পুনঃনির্দেশিত হয় যাতে আপনার মনোযোগ দেওয়া উচিত যে এতে থাকা আদেশগুলি স্টিডিন থেকে না পড়ে।
  • লুপগুলির মধ্যে থাকা কমান্ডগুলির জন্য, আমরা সেগুলি সফল হয় কি না সেদিকে আমরা মনোযোগ দিচ্ছি না। সাধারণত, ত্রুটি (ডিস্ক পূর্ণ, ত্রুটিগুলি পড়ার ...) শর্তগুলি সঠিকভাবে সমতুল্যতার চেয়ে খারাপভাবে পরিচালিত হবে ।

আমরা যদি উপরের কয়েকটি বিষয়কে সম্বোধন করতে চাই তবে তা হয়ে ওঠে:

while IFS= read -r line <&3; do
  {
    printf '%s\n' "$line" | cut -c3 || exit
  } 3<&-
done 3< file
if [ -n "$line" ]; then
    printf '%s' "$line" | cut -c3 || exit
fi

এটাই কম-বেশি স্পষ্ট হয়ে উঠছে।

আর্গুমেন্টের মাধ্যমে কমান্ডগুলিতে ডেটা পাঠানো বা ভেরিয়েবলগুলিতে তাদের আউটপুট পুনরুদ্ধার করা সহ আরও বেশ কয়েকটি সমস্যা রয়েছে:

  • আর্গুমেন্টের আকারের সীমাবদ্ধতা (কিছু পাঠ্য ইউটিলিটি বাস্তবায়নের একটি সীমাও রয়েছে, যদিও তাদের কাছে পৌঁছানোর প্রভাবটি সাধারণত কম সমস্যাযুক্ত)
  • NUL অক্ষর (পাঠ্য ইউটিলিটিগুলির সাথেও সমস্যা)।
  • যুক্তিগুলি বিকল্প হিসাবে নেওয়া হয় যখন তারা শুরু করে -(বা +কখনও কখনও)
  • বিভিন্ন কমান্ডের বিভিন্ন quirks সাধারণত এই লুপগুলিতে ব্যবহৃত হয় expr, test...
  • অসম্পূর্ণ উপায়ে মাল্টি-বাইট অক্ষর পরিচালনা করে এমন বিভিন্ন শেলের (সীমিত) পাঠ্য ম্যানিপুলেশন অপারেটরগুলি।
  • ...

সুরক্ষা বিবেচনা

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

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

আপনি যখন লুপগুলি ব্যবহার করতে পারেন।

TBD


24
পরিষ্কার (স্বচ্ছভাবে), পাঠযোগ্য এবং অত্যন্ত সহায়ক extremely আবার আপনাকে ধন্যবাদ. শেল স্ক্রিপ্টিং এবং প্রোগ্রামিংয়ের মধ্যে মৌলিক পার্থক্যের জন্য এটি ইন্টারনেটে আমি কোথাও দেখেছি এটিই সেরা ব্যাখ্যা।
ওয়াইল্ডকার্ড

2
এটি এর মতো পোস্টগুলি শুরুর স্ক্রিপ্টগুলি সম্পর্কে শিখতে এবং সূক্ষ্ম পার্থক্যগুলি দেখতে প্রাথমিকভাবে সহায়তা করে। আপনার শূন্যতা না পায় তা নিশ্চিত করতে re {VAR: -default_value as হিসাবে রেফারেন্সিং ভেরিয়েবল যুক্ত করা উচিত। এবং কোনও অ-সংজ্ঞায়িত মান উল্লেখ করার সময় আপনাকে চিৎকার করে চিঠির জন্য বিশেষ্যটি সেট করুন।
স্বাক্ষরবিহীন

6
@ এ ড্যানিশচেউস্কি, আমি মনে করি আপনি বিষয়টিটি মিস করছেন। হ্যাঁ cutউদাহরণস্বরূপ দক্ষ। cut -f1 < a-very-big-fileআপনি সি হিসাবে এটি লিখতে চাইলে আপনি যেমন দক্ষ হন তেমন দক্ষ, কী মারাত্মকভাবে অদক্ষ এবং ত্রুটিযুক্ত প্রবণটি একটি শেল লুপের cutপ্রতিটি লাইনটির জন্য অনুরোধ করছে a-very-big-fileযা এই উত্তরে তৈরি হওয়া বিন্দু। এটি অপ্রয়োজনীয় কোড লেখার বিষয়ে আপনার শেষ বক্তব্যের সাথে একমত হয়েছে যা আমাকে ভাবতে বাধ্য করে যে আমি সম্ভবত আপনার মন্তব্য বুঝতে পারি না।
স্টাফেন চেজেলাস

5
"45 বছরের মধ্যে, আমরা কমান্ডের শক্তিকে বাড়িয়ে তুলতে এবং তাদের কোনও কাজে সহযোগিতা করার জন্য সেই API এর চেয়ে ভাল পাইনি found" - প্রকৃতপক্ষে, পাওয়ারশেল, এক জন্য, বাইট স্ট্রিমের চেয়ে কাঠামোগত ডেটা অতিক্রম করে ভয়ঙ্কর পার্সিং সমস্যার সমাধান করেছে। শেলগুলি এখনও এটি ব্যবহার না করার একমাত্র কারণ (ধারণাটি বেশ কিছুদিনের জন্য রয়েছে এবং মূলত জাভা জুড়ে কিছুটা সময় স্ফটিক হয়ে গেছে যখন এখন-স্ট্যান্ডার্ড তালিকা এবং অভিধানের ধারক প্রকারগুলি মূলধারায় পরিণত হয়েছে) তাদের রক্ষণাবেক্ষণকারীরা এখনও তাতে একমত হতে পারেননি ব্যবহারের জন্য সাধারণ কাঠামোগত ডেটা ফর্ম্যাট (।
ivan_pozdeev

6
@ অলিভিয়ারডুলাক আমার মনে হয় এটি কিছুটা রসিকতা। এই বিভাগটি চিরকালের জন্য টিবিডি হবে।
মুড়ু

43

ধারণাগত এবং সুগম্যতা হিসাবে যতটা যায় শেলগুলি সাধারণত ফাইলগুলিতে আগ্রহী। তাদের "ঠিকানাযোগ্য ইউনিট" ফাইল এবং "ঠিকানা" ফাইলের নাম। শেলগুলিতে ফাইল অস্তিত্ব, ফাইলের ধরণ, ফাইলের নাম বিন্যাসকরণ (গ্লোব্বিংয়ের শুরু) পরীক্ষার সমস্ত ধরণের পদ্ধতি রয়েছে। শেলগুলির ফাইল সামগ্রীর সাথে কাজ করার জন্য খুব কম আদিম রয়েছে। শেল প্রোগ্রামারদের ফাইলের বিষয়বস্তু নিয়ে কাজ করার জন্য আরেকটি প্রোগ্রাম শুরু করতে হবে।

ফাইল এবং ফাইলের নামকরণের কারণে শেলটিতে পাঠ্য ম্যানিপুলেশন করা ধীর গতিযুক্ত, যেমনটি আপনি উল্লেখ করেছেন, তবে এর জন্য একটি অস্পষ্ট এবং চুক্তিবদ্ধ প্রোগ্রামিং স্টাইলও প্রয়োজন।


25

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

আমি মনে করি যে প্রশ্নকর্তা একটি সাধারণ ধরণের শেল স্ক্রিপ্টে আকর্ষণীয়, যা মূল কাজটি চালিয়ে যাওয়ার আগে কিছু কমান্ড-লাইন পার্সিং, পরিবেশ সেটিং, ফাইল এবং ডিরেক্টরিগুলি পরীক্ষা করা এবং আরও কিছুটা সূচনা দিয়ে শুরু করতে পারে: একটি বৃহত্তর মধ্য দিয়ে যাওয়া লাইন-ভিত্তিক পাঠ্য ফাইল।

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

তবে যখন আমরা বড় ফাইলটি প্রসেস করতে যাচ্ছি যার হাজার হাজার বা কয়েক মিলিয়ন লাইন থাকতে পারে, তখন প্রতিটি শখের জন্য শেল স্ক্রিপ্টের জন্য একটি সেকেন্ডের উল্লেখযোগ্য ভগ্নাংশ নেওয়া (এমনকি এটি কয়েক ডজন মিলি সেকেন্ড হলেও) নেওয়া ভাল নয়, যে কয়েক ঘন্টা পর্যন্ত যোগ করতে পারে।

আমাদের যখন অন্যান্য সরঞ্জামগুলি ব্যবহার করতে হবে এবং ইউনিক্স শেল স্ক্রিপ্টগুলির সৌন্দর্য হ'ল এটি আমাদের পক্ষে এটি করা খুব সহজ করে তোলে।

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

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

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

সহজ টুলগুলি অন্তর্ভুক্ত head, tail, grep, sort, cut, tr, sed, join(যখন 2 ফাইল মার্জ), এবং awkএক-liners, অনেক অন্যদের মধ্যে। প্যাটার্ন-ম্যাচিং এবং sedকমান্ডগুলি দিয়ে কিছু লোক কী করতে পারে তা অবাক করা ।

যখন এটি আরও জটিল হয়ে ওঠে এবং আপনাকে প্রতিটি লাইনে সত্যিই কিছু যুক্তি প্রয়োগ করতে হবে, awkএটি একটি ভাল বিকল্প - হয় ওয়ান-লাইনার (কিছু লোক 'এক লাইনে পুরো পুরো বিশ্রী স্ক্রিপ্টগুলি রাখে, যদিও এটি খুব পঠনযোগ্য নয়) বা একটিতে সংক্ষিপ্ত বাহ্যিক লিপি।

awkবর্ণিত ভাষা হিসাবে (আপনার শেলের মতো) এটি আশ্চর্যজনক যে এটি এতটা দক্ষতার সাথে লাইন-বাই-লাইন প্রসেসিং করতে পারে তবে এটি এর জন্য নির্মিত এবং এটি সত্যিই খুব দ্রুত।

এবং তারপরে Perlএবং অনেকগুলি স্ক্রিপ্টিং ভাষা রয়েছে যা পাঠ্য ফাইলগুলি প্রক্রিয়াকরণে খুব ভাল, এবং প্রচুর দরকারী লাইব্রেরি সহ আসে।

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

কিছু চূড়ান্ত ইঙ্গিত:

  • আপনার মূল শেল স্ক্রিপ্টটি দিয়ে শুরু করতে ভুলবেন না export LANG=C, বা অনেক সরঞ্জাম আপনার সাধারণ-পুরানো-এএসসিআইআই ফাইলগুলিকে ইউনিকোড হিসাবে বিবেচনা করবে, এগুলিকে অনেক ধীর করে দেবে or
  • পরিবেশ নির্বিশেষে export LC_ALL=Cআপনি যদি sortধারাবাহিক ক্রম উত্পাদন করতে চান তবে সেটিংটিকেও বিবেচনা করুন !
  • আপনার যদি sortআপনার ডেটা দরকার হয় , তবে এটি সম্ভবত অন্য সব কিছুর চেয়ে বেশি সময় (এবং সংস্থানসমূহ: সিপিইউ, মেমরি, ডিস্ক) নেবে, সুতরাং sortকমান্ডের সংখ্যা এবং তারা যে ফাইলগুলি বাছাই করছেন তার আকার হ্রাস করার চেষ্টা করুন
  • একটি একক পাইপলাইন, যখন সম্ভব হয় সাধারণত সর্বাধিক দক্ষ - একাধিক পাইপলাইন ধারাবাহিকভাবে মধ্যবর্তী ফাইলগুলির সাথে চালানো, আরও পঠনযোগ্য এবং ডিবাগ-সক্ষম হতে পারে, তবে আপনার প্রোগ্রামের সময়টি আরও বাড়িয়ে তুলবে

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

14

হ্যাঁ কিন্তু...

Stéphane Chazelas এর সঠিক উত্তর উপর ভিত্তি করে তৈরি নির্দিষ্ট বাইনেরিতে মত প্রতি টেক্সট অপারেশন প্রতিনিধিরূপে ধারণা grep, awk, sedএবং অন্যদের।

যেহেতু নিজেই অনেক কিছু করতে সক্ষম, তাই কাঁটাচামচ ফেলে দেওয়া দ্রুত হতে পারে (এমনকি সমস্ত কাজ করার জন্য অন্য দোভাষী চালানোর চেয়েও)।

নমুনার জন্য, এই পোস্টে একবার দেখুন:

https://stackoverflow.com/a/38790442/1765658

এবং

https://stackoverflow.com/a/7180078/1765658

পরীক্ষা এবং তুলনা ...

অবশ্যই

ব্যবহারকারীর ইনপুট এবং সুরক্ষা সম্পর্কে কোনও বিবেচনা নেই !

অধীনে ওয়েব অ্যাপ্লিকেশন লিখবেন না !!

কিন্তু সার্ভার প্রশাসন কর্ম, যেখানে অনেক জন্য স্থানে ব্যবহার করা যেতে পারে , builtins ব্যাশ ব্যবহার খুব দক্ষ হতে পারে।

আমার অর্থ:

বিন ব্যবহারের মতো সরঞ্জাম লেখার ব্যবস্থা প্রশাসনের চেয়ে এক ধরণের কাজ নয়।

সুতরাং একই মানুষ না!

যেখানে সিসাডমিনদের জানতে হবে shell, তারা তার পছন্দসই (এবং সর্বাধিক পরিচিত) সরঞ্জামটি ব্যবহার করে প্রোটোটাইপগুলি লিখতে পারতেন ।

যদি এই নতুন ইউটিলিটি (প্রোটোটাইপ) সত্যিই ব্যবহারযোগ্য হয় তবে কিছু অন্যান্য লোক আরও কিছু বরাদ্দকৃত ভাষা ব্যবহার করে উত্সর্গীকৃত সরঞ্জাম বিকাশ করতে পারে।


1
ভালো উদাহরণ. আপনার পন্থা অবশ্যই লোললাক্সের তুলনায় আরও দক্ষ, তবে খেয়াল করুন যে টেনসিবাইয়ের উত্তর (এই আইএমওটি করার সঠিক উপায়, এটি শেল লুপগুলি ব্যবহার না করে) আপনার চেয়ে তাত্পর্যপূর্ণতার অর্ডার is আপনি যদি ব্যবহার না করেন তবে আপনার অনেক দ্রুত bash। (আমার সিস্টেমে আমার পরীক্ষায় ksh93 দিয়ে 3 গুণ বেশি দ্রুত) bashসাধারণত ধীরতম শেল হয়। এমনকি zshসেই স্ক্রিপ্টে দ্বিগুণ দ্রুত। অব্যক্ত ভেরিয়েবল এবং এর ব্যবহার নিয়ে আপনার কয়েকটি সমস্যা রয়েছে read। সুতরাং আপনি এখানে আমার পয়েন্ট অনেক চিত্রিত করছেন।
স্টাফেন চেজেলাস

@ স্টাফেনচাজেলাস আমি সম্মত, বাশ সম্ভবত লোকেরা আজ সবচেয়ে ধীরতম শেল ব্যবহার করতে পারে তবে যেহেতু সবচেয়ে বেশি ব্যবহৃত হয়।
এফ। হাউরি

@ স্টাফেনচাজেলাস আমি আমার উত্তরের জন্য পার্ল সংস্করণ পোস্ট করেছি
এফ। হাউরি

1
@Tensibai, আপনি পাবেন POSIXsh , awk , ব্যান্ডউইডথ , grep, ed, ex, cut, sort, joinব্যাশ চেয়ে বেশি নির্ভরযোগ্যতা সঙ্গে ... সমস্ত বা পার্ল।
ওয়াইল্ডকার্ড

1
ইউএনএল সম্পর্কিত সমস্ত সিস্টেমের মধ্যে @ টেনসিবাই, তাদের বেশিরভাগ (সোলারিস, ফ্রিবিএসডি, এইচপি / ইউএক্স, এআইএক্স, সর্বাধিক এম্বেডেড লিনাক্স সিস্টেম ...) bashডিফল্টরূপে ইনস্টলড আসে না । bashবেশিরভাগ শুধুমাত্র অ্যাপল MacOS এবং গনুহ সিস্টেম (আমি অনুমান যে কি কল পাওয়া যায় প্রধান ডিস্ট্রিবিউশন ,) যদিও অনেক সিস্টেম এছাড়াও একটি ঐচ্ছিক প্যাকেজ হিসাবে এটা আছে (যেমন zsh, tcl, python...)
Stéphane Chazelas
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.