এক্সট্রা পাটিগণিত মধ্যে প্রথম: 3 * (2 + 1)


59

expr বন্ধনী পছন্দ করে না বলে মনে হচ্ছে (স্পষ্টত অপারেটরের অগ্রাধিকার গণিতে ব্যবহৃত):

expr 3 * (2 + 1)
bash: syntax error near unexpected token `('

ব্যাশে অপারেটরের অগ্রাধিকার কীভাবে প্রকাশ করবেন?

উত্তর:


40

letব্যাশ বিল্টিন ব্যবহারের অন্য উপায় :

$ let a="3 * (2 + 1)"
$ printf '%s\n' "$a"
9

বিঃদ্রঃ

হিসাবে @ Stéphane Chazelas নির্দিষ্ট , এ bashআপনি ব্যবহার করা উচিত ((...))উপর গাণিতিক করতে exprবা letস্পষ্টতা জন্য।

বহনযোগ্যতার জন্য @ বার্নহার্ড উত্তরের$((...)) মতো ব্যবহার করুন ।


1
+1 আরও পাঠযোগ্য! আমি আমার প্রশ্নটি + উত্তরটি কেবল আমার সহকর্মী লিনাক্স ব্যবহারকারীদের জন্য সহায়ক মনে করে পোস্ট করেছি, তবে এখন আমি অন্যান্য উত্তরগুলি থেকে প্রচুর উপকার পাচ্ছি :-)
নিকোলাস রাউল

3
ব্যবহার করার কোনও কারণ নেই let। এটি এর চেয়ে বেশি কোনও স্ট্যান্ডার্ড বা পোর্টেবল নয় (( a = 3 * (2 + 1) ))(উভয়ই এসেছিল kshএবং কেবলমাত্র কেএসএইচ, ব্যাশ এবং জেডএসে পাওয়া যায়) এবং এটি কম সুসংগঠিত বা উদ্ধৃত করা সহজ। a=$((3 * (2 + 1)))পোর্টেবল হতে ব্যবহার করুন ।
স্টাফেন চেজেলাস

2
আমি এটি ভুল বলছি না, আমি বলছি এটি আরও ভাল বিকল্প হিসাবে ব্যবহার করা উচিত নয় (একটি সুশাসনের ((a = 3 * (2 + 1) ))জন্য একটি, বহনযোগ্যতার জন্য একটি a=$((3 * (2 + 1)))), সুতরাং এটি আপনার বা আপনার উত্তরের বিরুদ্ধে নয় তবে এটি নির্বাচিত উত্তর হওয়ার বিরুদ্ধে নয় এবং শীর্ষ স্কোরার।
স্টাফেন চেজেলাস

@ স্টাফেনচেজেলাস: আমার উত্তর আপডেট করেছেন!
কিউংলম

আমি সবসময় ব্যবহার করেছি a=1 $[a+2]বা a=1 b=2 $[a+b]। তাদের সিনট্যাক্স এড়ানোর কারণ কি?
গর্ডন

73

পরিবর্তে আপনি পাটিগণিতের সম্প্রসারণ ব্যবহার করতে পারেন।

echo "$(( 3 * ( 2 + 1 ) ))"
9

আমার ব্যক্তিগত মতে এটি ব্যবহারের চেয়ে কিছুটা সুন্দর লাগছে expr

থেকে man bash

পাটিগণিতের সম্প্রসারণ পাটিগণিতের বিস্তৃতি পাটিগণিতের প্রকাশের মূল্যায়ন এবং ফলাফলের পরিবর্তনের অনুমতি দেয়। পাটিগণিতের বিস্তারের জন্য ফর্ম্যাটটি হ'ল:

         $((expression))

এক্সপ্রেশনটি এমনভাবে বিবেচনা করা হয় যেন এটি ডাবল কোটের মধ্যে থাকে তবে প্রথম বন্ধনের ভিতরে ডাবল উদ্ধৃতিটি বিশেষভাবে বিবেচনা করা হয় না। অভিব্যক্তির সমস্ত টোকেনগুলি প্যারামিটার সম্প্রসারণ, স্ট্রিং সম্প্রসারণ, কমান্ড প্রতিস্থাপন এবং উদ্ধৃতি অপসারণের মধ্য দিয়ে যায়। পাটিগণিতের বিস্তৃতি বাসা বাঁধতে পারে।

মূল্যায়ন মূল্যায়ন মূল্যায়ন অধীনে নীচে তালিকাভুক্ত নিয়ম অনুযায়ী সম্পাদন করা হয়। যদি অভিব্যক্তিটি অবৈধ হয় তবে ব্যাশ ব্যর্থতা নির্দেশ করে একটি বার্তা প্রিন্ট করে এবং কোনও প্রতিস্থাপন ঘটে না।


1
পঠনযোগ্যতা বাদে, পাটিগণিতটি করার জন্য এটি অতিরিক্ত প্রক্রিয়া করারও প্রয়োজন হয় না; এটি নিজেই খোল দ্বারা পরিচালিত হয়।
চিপনার

নোট করুন যে পসিক্স শেলগুলিতে, এটি শব্দ বিভাজনের বিষয়, সুতরাং এটি তালিকা প্রসঙ্গে উল্লেখ করা ভাল অভ্যাস।
স্টাফেন চেজেলাস

আমি যখন বাশ শেলটিতে এটি চেষ্টা করি তখন আমি 'অবৈধ ভেরিয়েবলের নাম
পাই

40

exprআধুনিক শেলগুলিতে পাটিগণিতের জন্য ব্যবহার করার কোনও কারণ নেই ।

পসিক্স এক্সপেনশন $((...))অপারেটরটিকে সংজ্ঞায়িত করে । সুতরাং আপনি এটি shপসিক্সের সমস্ত আনুগত্যের শেলগুলিতে ( সমস্ত আধুনিক ইউনিক্স-পছন্দ, ড্যাশ, বাশ, যশ, ম্যাক্স, জেডএস, পশ, কেশ ...) ব্যবহার করতে পারেন।

a=$(( 3 * (2 + 1) ))
a=$((3*(2+1)))

kshএছাড়াও একটি letবিল্টিন প্রবর্তন করা হয়েছে যা একই ধরণের পাটিগণিতের এক্সপ্রেশনটি পাস করা হয়, কোনও কিছুর মধ্যে প্রসারিত হয় না তবে এক্সপ্রেশনটি 0 তে আসে কি না তার ভিত্তিতে একটি প্রস্থান স্থিতি ফিরে আসে expr:

if let 'a = 3 * (2 + 1)'; then
  echo "$a is non-zero"
fi

যাইহোক, উদ্ধৃতিটি এটিকে বিশ্রী করে তোলে এবং খুব সুগঠিত নয় ( exprঅবশ্যই ঠিক তেমন পরিমাণে নয় ), kshএকটি ((...))বিকল্প রূপও প্রবর্তন করে :

if (( a = 3 * (2 + 1) )) && (( 3 > 1 )); then
  echo "$a is non-zero and 3 > 1"
fi
((a+=2))

যা অনেক বেশি সুস্পষ্ট এবং পরিবর্তে ব্যবহার করা উচিত।

letএবং ((...))একমাত্র পাওয়া যায় ksh, zshএবং bash$((...))সিনট্যাক্স পছন্দের করা উচিত অন্যান্য শাঁস থেকে বহনযোগ্যতা প্রয়োজন, exprশুধুমাত্র প্রাক POSIX বোর্ন মত শাঁস (সাধারণত বোর্ন শেল বা Almquist শেল প্রথম সংস্করণ) জন্য প্রয়োজন হয়।

নন-বোর্ন ফ্রন্টে বিল্ট-ইন গাণিতিক অপারেটর সহ কয়েকটি শেল রয়েছে:

  • csh/ tcsh(আসলে অন্তর্নির্মিত মূল্যায়ন সহ প্রথম ইউনিক্স শেল):

    @ a = 3 * (2 + 1)
  • akanga(উপর ভিত্তি করে rc)

    a = $:'3 * (2 + 1)'
  • ইতিহাসের নোট হিসাবে, অ্যালকুইস্ট শেলের মূল সংস্করণ, যেমন 1989 সালে ইউজনেটে ​​পোস্ট হয়েছিল একটি exprবিল্টিন ছিল (আসলে এতে মিশে গেছে test), তবে এটি পরে সরিয়ে ফেলা হয়েছিল।


স্টাফেন, আমি আপনার কাছ থেকে প্রতিদিন নতুন কিছু শিখি। আমি আপনার পসিক্স শেল জ্ঞানের খুব প্রশংসা করি!
ম্যাটবিয়ানকো

কীভাবে : $((a = a*2))?
আর্থার 2e5

আমার যদি ভাসমান পয়েন্ট থাকে? আমার অভিব্যক্তি a = $ ((-14 + 0.2 * (1 + 2 + 3)))। ত্রুটির টোকেন হ'ল ".2 * (1 + 2 + 3)"
ব্লেইস

@ ব্লাইজ, তারপরে আপনার এমন শেল দরকার যা $((...))zsh, ksh93 বা যশের মতো ভাসমান পয়েন্টগুলিকে সমর্থন করে ।
স্টাফেন চেজেলাস

16

exprএটি একটি বাহ্যিক আদেশ, এটি বিশেষ শেল সিনট্যাক্স নয় not সুতরাং, আপনি যদি exprশেল বিশেষ অক্ষর দেখতে চান তবে আপনাকে সেগুলি উদ্ধৃত করে শেল পার্সিং থেকে তাদের রক্ষা করতে হবে। তদতিরিক্ত, exprপ্রতিটি নম্বর এবং অপারেটরের পৃথক প্যারামিটার হিসাবে পাস করার প্রয়োজন। এভাবে:

expr 3 \* \( 2 + 1 \)

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

echo "$((3 * (2 + 1)))"

কনস্ট্রাক্ট $((…))গাণিতিক এক্সপ্রেশন (দশমিক লেখা) ফলাফলের সাথে প্রাসঙ্গিক বিস্তৃতি ঘটে। বেশিরভাগ শাঁসের মতো বাশ কেবলমাত্র পূর্ণসংখ্যার গাণিতিক মডুলো 2 64 (বা মডেলো 2 32 বাশ এর পুরানো সংস্করণ এবং 32-বিট মেশিনে কিছু অন্যান্য শেলের জন্য সমর্থন করে) সমর্থন করে।

আপনি যখন অ্যাসাইনমেন্টগুলি সম্পাদন করতে চান বা এক্সপ্রেশন 0 হয় কিনা তা পরীক্ষা করতে চান তবে ফলাফলটির বিষয়ে চিন্তা করবেন না বাশ একটি অতিরিক্ত সুবিধাযুক্ত বাক্য গঠন সরবরাহ করে । এই কনস্ট্রাক্টটি ksh এবং zsh- তে উপস্থিত রয়েছে তবে সরল sh- তে নেই।

((x = 3 * (2+1)))
echo "$x"
if ((x > 3)); then 

পূর্ণসংখ্যার গাণিতিক ছাড়াও exprকয়েকটি স্ট্রিং ম্যানিপুলেশন ফাংশন সরবরাহ করে। এগুলিও POSIX শেলগুলির বৈশিষ্ট্যগুলির দ্বারা গ্রহণ করা হয়, একটি ব্যতীত: expr STRING : REGEXPস্ট্রিংটি নির্দিষ্ট রেজপ্লেক্সের সাথে মেলে কিনা তা পরীক্ষা করে। কোনও পসিক্স শেল বাহ্যিক সরঞ্জামগুলি ব্যতীত এটি করতে পারে না, তবে ব্যাশ এটির সাহায্যে [[ STRING =~ REGEXP ]](একটি ভিন্ন রেজিপ্লেক্স সিনট্যাক্স সহexprএকটি সর্বোত্তম সরঞ্জাম এবং বিআরই ব্যবহার করে, ব্যাশ পূর্ব ব্যবহার করে)।

আপনি যদি 20-বছরের পুরানো সিস্টেমে চালিত স্ক্রিপ্টগুলি সংরক্ষণ না করে থাকেন, আপনার আর exprকখনও এটির অস্তিত্বের দরকার নেই। শেল পাটিগণিত ব্যবহার করুন।


expr foo : '\(.\)'পাঠ্য নিষ্কাশনও। bashএর BASH_REMATCHঅনুরূপ কিছু অর্জন। এটি স্ট্রিং তুলনাও [করে , যা পসিক্স না করে (যদিও এটির জন্য ব্যবহারের উপায়গুলি কল্পনাও করা যায় sort)।
স্টাফেন চেজেলাস

সিনট্যাক্স স্থানধারক হিসাবে আন্ডারস্কোর --- আপনি একজন স্কিমার, @ গাইলস? :]
রুবিট্রিস্টেডনো

1
@ রুবিটায়রোয়ালডোন আমি এখানে একটি আন্ডারস্কোর ব্যবহার করি নি। আপনি কি ইউ + 2026 হারিওজেন্টাল এললিপসিসটি ভুলভাবে পড়ছেন? যদি তা হয় তবে আরও বড় ফন্ট ব্যবহার করে দেখুন।
গিলস

@ গাইলস - ঠিক আছে, হ্যাঁ, এটি কেবল আমার ফন্টের আকারের কারণে আন্ডারস্কোরের মতো দেখাচ্ছে। আমার জন্য, "স্কিমার" একটি পরিপূরক এবং এটি উপবৃত্ত বনাম আন্ডারস্কোরের মতো কোনওভাবেই এর অর্থ পরিবর্তিত করে না ... এটির উপরে
ফাঁকি

12

উদ্ধৃতি সহ প্রথম বন্ধনী ব্যবহার করুন:

expr 3 '*' '(' 2 '+' 1 ')'
9

উদ্ধৃতিগুলি বাশকে বাক্য সিনট্যাক্স হিসাবে প্রথম বন্ধনী ব্যাখ্যা করতে বাধা দেয়।


2
নিকোলাস যা চিত্রিত করে তবে ব্যাখ্যা করে না তা হ'ল exprকমান্ড লাইনের টোকেনগুলি অবশ্যই স্পেস দিয়ে আলাদা করতে হবে; তাই; উদাহরণস্বরূপ, expr 3 "*" "(2" "+" "1)" কাজ করবে না । (এছাড়াও, বিটিডাব্লু, আপনার সম্ভবত উদ্ধৃতি দেওয়ার দরকার নেই +))
জি-ম্যান

প্রথম বন্ধনীগুলি কীওয়ার্ড নয় whileএবং [[এগুলি সিনট্যাক্স। যদি তারা কীওয়ার্ড হয় তবে তাদের কমান্ড আর্গুমেন্ট হিসাবে ব্যাখ্যা করা হবে না। আপনার উদ্ধৃতি দরকার যাতে বাশগুলি তাদের বিশ্লেষণ না করে পরিবর্তে একটি স্ট্রিং আক্ষরিক দেখায়।
গিলস

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.