কোনও ভেরিয়েবল খালি থাকলে বা কেবলমাত্র ফাঁকা স্থান থাকলে আমি কীভাবে পরীক্ষা করতে পারি?


240

নিম্নলিখিত বাশ বাক্য গঠনটি paramখালি না হলে যাচাই করে :

 [[ !  -z  $param  ]]

উদাহরণ স্বরূপ:

param=""
[[ !  -z  $param  ]] && echo "I am not zero"

কোন আউটপুট এবং তার জরিমানা।

তবে যখন paramএকটি (বা আরও) স্পেস অক্ষর ব্যতীত খালি থাকে তখন কেসটি আলাদা হয়:

param=" " # one space
[[ !  -z  $param  ]] && echo "I am not zero"

"আমি শূন্য নই" আউটপুট।

খালি হিসাবে কেবল স্থানের অক্ষর ধারণ করে এমন ভেরিয়েবলগুলি বিবেচনা করতে আমি কীভাবে পরীক্ষার পরিবর্তন করতে পারি?


4
থেকে man test: -z STRING - the length of STRING is zero। আপনি যদি সমস্ত স্থান সরিয়ে নিতে চান তবে$param${param// /}
dchirikov

6
বাহtrim() কোনও সাধারণ * নিক্সের অভ্যন্তরে কোনও সাধারণ ফাংশন নেই? এত সহজ কিছু অর্জনের জন্য অনেকগুলি বিভিন্ন হ্যাক ...
ADTC

6
@ ADTC $ (সেডস / ^ \ s + | \ s + $ // জি '<<< $ স্ট্রিং) আমার কাছে যথেষ্ট সহজ বলে মনে হচ্ছে। চাকা পুনরুদ্ধার কেন?
জবোম্যান

3
কারণ এটি আরও
হালকা

1
শুধু যে [[ ! -z $param ]]সমতুল্য লক্ষ করা test ! -z $param
নোহ সুসমান

উত্তর:


292

প্রথমে লক্ষ করুন যে -zপরীক্ষাটি স্পষ্টভাবে এর জন্য:

স্ট্রিংয়ের দৈর্ঘ্য শূন্য

অর্থাৎ, কেবল শূণ্যস্থানযুক্ত একটি স্ট্রিংয়ের নিচে সত্য হওয়া উচিত নয়-z , কারণ এটির দৈর্ঘ্য অ-শূন্য রয়েছে।

আপনি যা চান তা হ'ল প্যাটার্ন প্রতিস্থাপনের প্যারামিটার সম্প্রসারণটি ব্যবহার করে ভেরিয়েবল থেকে স্পেসগুলি সরিয়ে ফেলা :

[[ -z "${param// }" ]]

এটি paramভেরিয়েবলটি প্রসারিত করে এবং প্যাটার্নের সমস্ত মিলকে (একক স্থান) কিছু না দিয়ে প্রতিস্থাপন করে , সুতরাং এর মধ্যে কেবল ফাঁকা ফাঁকা স্ট্রিংটি খালি স্ট্রিংয়ে প্রসারিত হবে।


যে কিভাবে কাজ করে মোদ্দা কথা হল ${var/pattern/string}প্রথম দীর্ঘতম ম্যাচ প্রতিস্থাপন patternসঙ্গে string। (উপরে হিসাবে) যখন patternশুরু হয় /তখন এটি সমস্ত ম্যাচ প্রতিস্থাপন করে। প্রতিস্থাপনটি খালি থাকায় আমরা চূড়ান্ত /এবং stringমানটি বাদ দিতে পারি :

$ {প্যারামিটার / প্যাটার্ন / পংক্তি}

প্যাটার্ন ঠিক ফাইলের নাম সম্প্রসারণ হিসেবে একটি প্যাটার্ন উত্পাদন করতে প্রসারিত করা হয়। প্যারামিটারটি প্রসারিত করা হয় এবং এর মানটির সাথে প্যাটার্নের দীর্ঘতম মিলটি স্ট্রিংয়ের সাথে প্রতিস্থাপিত হয় । তাহলে প্যাটার্ন '/' দিয়ে শুরু হয়, সব ম্যাচ প্যাটার্ন সঙ্গে প্রতিস্থাপিত হয় স্ট্রিং । সাধারণত প্রথম ম্যাচটি প্রতিস্থাপন করা হয়। ... স্ট্রিং যদি নাল হয় তবে প্যাটার্নের মিলগুলি মুছে ফেলা হবে এবং / নিম্নলিখিত প্যাটার্নটি বাদ দেওয়া যেতে পারে।

এত কিছুর পরেও, আমরা ${param// }সমস্ত স্পেস মুছতে শেষ করি ।

মনে রাখবেন যে kshএটি উপস্থিত (যেখানে এটি উদ্ভূত হয়েছিল) উপস্থিত রয়েছে zshএবং bashসেই বাক্য গঠনটি পসিক্স নয় এবং shস্ক্রিপ্টগুলিতে ব্যবহার করা উচিত নয় ।


ব্যবহার sedতারা বলেছিল ... কেবল echoপরিবর্তনশীল তারা বলেছিল ...
মাইকেজটার

1
হুম। যদি এটি হয় ${var/pattern/string}তবে [[ -z ${param/ /} ]]স্ল্যাশগুলির মধ্যে স্থানটি প্যাটার্ন হিসাবে হওয়া উচিত এবং স্ট্রিং হওয়ার পরে কিছুই নয়?
জেসি

@ জেসি চিশম "প্রতিস্থাপনটি খালি থাকায় আমরা চূড়ান্ত / এবং স্ট্রিংয়ের মান বাদ দিতে পারি"; "যদি স্ট্রিংটি নাল হয়, প্যাটার্নের মিলগুলি মুছে ফেলা হয় এবং / নিম্নলিখিত প্যাটার্নটি বাদ দেওয়া যেতে পারে" "
মাইকেল হোমার

6
@ মিশেলহোমের উত্তরটি [[ -z "${param// }" ]]নিশ্চিতরূপে দেখতে patternখালি খালি এবং এটি replacement stringএকটি একক স্থান। আহ! আমি এখন এটি দেখতে পাই if pattern begins with a slashআমি সেই অংশটি মিস করেছি। সুতরাং প্যাটার্নটি রয়েছে / এবং স্ট্রিংটি ছেড়ে যায় এবং তাই খালি। ধন্যবাদ।
জেসি চিশলম

বাশ নোট: যদি সেট-ও নুনসেটে (সেট-ইউ) চলমান থাকে এবং প্যারাম আনসেট না হয়ে থাকে (নাল বা স্পেসে ভরা পরিবর্তে) তবে এটি একটি আনবাউন্ড ভেরিয়েবল ত্রুটি তৈরি করবে। (সেট + ইউ; .....) এই পরীক্ষাটি ছাড় দেবে।
ব্রায়ান ক্রিসম্যান

31

স্ট্রিংয়ে কেবল অনুমোদিত সেটে অক্ষর রয়েছে তা যাচাই করার সহজ উপায়টি অননুমোদিত অক্ষরের উপস্থিতির জন্য পরীক্ষা করা। সুতরাং, স্ট্রিংটিতে কেবল ফাঁকা স্থান রয়েছে কিনা তা পরীক্ষার পরিবর্তে, স্ট্রিংটিতে স্থান ব্যতীত অন্য কিছু অক্ষর রয়েছে কিনা তা পরীক্ষা করুন। বাশ, কেশ বা জেডশায়:

if [[ $param = *[!\ ]* ]]; then
  echo "\$param contains characters other than space"
else
  echo "\$param consists of spaces only"
fi

"কেবলমাত্র স্থানগুলির সমন্বয়ে" খালি (বা আনসেট) ভেরিয়েবলের কেস অন্তর্ভুক্ত।

আপনি যে কোনও সাদা স্থানের অক্ষরের জন্য পরীক্ষা করতে চাইতে পারেন। [[ $param = *[^[:space:]]* ]]স্থানীয় সেটিংস ব্যবহার করার জন্য, বা শ্বেতস্পেস অক্ষরগুলির যে কোনও স্পষ্ট তালিকা আপনি পরীক্ষা করতে চান, যেমন [[ $param = *[$' \t\n']* ]]স্থান, ট্যাব বা নিউলাইন পরীক্ষা করার জন্য ব্যবহার করুন।

=অভ্যন্তরের সাথে কোনও প্যাটার্নের সাথে স্ট্রিংয়ের মিল করা [[ … ]]হ'ল কেএস এক্সটেনশন (বাশ এবং জেডএসে উপস্থিত)। যে কোনও বোর্ন / পসিক্স-স্টাইলে, আপনি caseকোনও নকশার বিপরীতে স্ট্রিংয়ের সাথে মিলের জন্য কনস্ট্রাক্টটি ব্যবহার করতে পারেন । নোট করুন যে স্ট্যান্ডার্ড শেল প্যাটার্নগুলি বেশিরভাগ নিয়মিত এক্সপ্রেশন সিনট্যাক্সে পছন্দ না করে !একটি অক্ষর সেটকে উপেক্ষা করতে ব্যবহার করে ^

case "$param" in
  *[!\ ]*) echo "\$param contains characters other than space";;
  *) echo "\$param consists of spaces only";;
esac

সাদা স্থানের অক্ষরের জন্য পরীক্ষা করতে $'…'সিনট্যাক্সটি ksh / bash / zsh এর সাথে নির্দিষ্ট; আপনি আপনার স্ক্রিপ্টে এই অক্ষরগুলি অক্ষরে অক্ষরে sertোকাতে পারেন (দ্রষ্টব্য যে একটি নিউলাইন উদ্ধৃতিতে থাকতে হবে, যেমন ব্যাকস্ল্যাশ + নিউলাইন কিছুতেই প্রসারিত হয় না), বা এগুলি উত্পন্ন করতে পারে, যেমন

whitespace=$(printf '\n\t ')
case "$param" in
  *[!$whitespace]*) echo "\$param contains non-whitespace characters";;
  *) echo "\$param consists of whitespace only";;
esac

এটি প্রায় দুর্দান্ত - তবে এখনও এটি জিজ্ঞাসা করা প্রশ্নের উত্তর দেয় না। এটি বর্তমানে আপনাকে একটি আনসেট বা খালি শেল ভেরিয়েবলের মধ্যে পার্থক্য বলতে পারে এবং যার মধ্যে কেবল ফাঁকা স্থান রয়েছে। আপনি যদি আমার পরামর্শ গ্রহণ করেন তবে আপনি পরম সম্প্রসারণ ফর্মটি যুক্ত করবেন যা এখনও অন্য কোনও উত্তর দ্বারা প্রকাশিত হয়নি যা স্পষ্টভাবে সেট হওয়ার জন্য শেল ভেরিয়েবল পরীক্ষা করে - মানে ${var?not set}এই পরীক্ষায় উত্তীর্ণ হওয়া এবং বেঁচে থাকা নিশ্চিত করবে যে আপনার সাথে মিলিত একটি চলক একটি চূড়ান্ত *) caseপ্রভাব ফেলবে উত্তর, উদাহরণস্বরূপ।
মাইক্রজারভ

সংশোধন - এটি প্রকৃতপক্ষে জিজ্ঞাসিত প্রশ্নের উত্তর দেবে , তবে পরে এটি এমনভাবে সম্পাদনা করা হয়েছে যে এটি মূলত প্রশ্নের অর্থকে পরিবর্তন করে এবং তাই আপনার উত্তরটিকে অকার্যকর করে দেয়।
মাইক্রজারভ

আপনি প্রয়োজন [[ $param = *[!\ ]* ]]মধ্যে mksh
স্টাফেন চেজেলাস

20

POSIXly:

case $var in
  (*[![:blank:]]*) echo '$var contains non blank';;
  (*) echo '$var contains only blanks or is empty or unset'
esac

ফাঁকা , ফাঁকা , খালি , আনসেটের মধ্যে পার্থক্য করতে :

case ${var+x$var} in
  (x) echo empty;;
  ("") echo unset;;
  (x*[![:blank:]]*) echo non-blank;;
  (*) echo blank
esac

[:blank:]অনুভূমিক ব্যবধান অক্ষরের জন্য (এএসসিআইআই-তে স্পেস এবং ট্যাব, তবে সম্ভবত আপনার লোকেলে আরও কয়েকটি রয়েছে; কিছু সিস্টেমে অবিচ্ছেদী স্থান (যেখানে উপলব্ধ) অন্তর্ভুক্ত থাকবে, কিছু থাকবে না)। ভাল হিসাবে আপনি (সম্পর্কে newline বা ফর্ম-ফিড মত) উল্লম্ব ফাঁক অক্ষর চান, প্রতিস্থাপন [:blank:]সঙ্গে [:space:]


পসিক্সলি আদর্শ কারণ এটি (তর্কযোগ্যভাবে আরও ভাল) ড্যাশ দিয়ে কাজ করবে।
কেন শার্প

zshএতে সমস্যা আছে বলে মনে হচ্ছে [![:blank:]], এটি উত্থাপন করে :bঅবৈধ সংশোধক। ইন shএবং kshঅনুকরণ করুন, এটি ইভেন্ট উত্থাপন করে[
কুওল্ম

@ কুওগলম, আপনি কি চেষ্টা করেছেন? var=foo zsh -c 'case ${var+x$var} in (x*[![:blank:]]*) echo x; esac'আমার জন্য ঠিক আছে। ইভেন্টটি পাওয়া যায় নি এটি কেবল ইন্টারেক্টিভ শেলের জন্য।
স্টাফেন চেজেলাস

@ স্টাফেনচাজেলাস: আহ, ঠিক আছে, আমি ইন্টারেক্টিভ শেল দিয়ে চেষ্টা করেছি। :bঅবৈধ পরিবর্তক একটু অদ্ভুত।
cuonglm

1
@FranklinYu, অপারেটিং সিস্টেম চালু / এক্স shহয় bashনির্মিত --enable-xpg-echo-defaultএবং --enable-strict-posix-defaultতাই ইউনিক্স অনুবর্তী (যা জড়িত হতে যেমন echo '\t'একটি ট্যাব outputting)।
স্টাফেন চেজেলাস

4

ভাল স্ক্রিপ্টিং ভাষায় স্ক্রিপ্টের পরিবর্তে শেল স্ক্রিপ্ট লেখার একমাত্র কারণ হ'ল চূড়ান্ত পোর্টেবিলিটি যদি ওভাররাইডিং উদ্বেগ হয়। উত্তরাধিকার /bin/shএকমাত্র জিনিস আপনি সম্ভবত আপনি থাকতে নিশ্চিত থাকতে পারি, কিন্তু উদাহরণস্বরূপ পার্ল হয় আরো ব্যাশ চেয়ে প্রাপ্তিসাধ্য ক্রস-প্ল্যাটফর্ম হওয়ার সম্ভাবনা। অতএব, এমন শেল স্ক্রিপ্টগুলি কখনই লিখবেন না যেগুলি এমন বৈশিষ্ট্যগুলি ব্যবহার করে যা প্রকৃতপক্ষে সর্বজনীন নয় - এবং মনে রাখবেন যে বেশ কয়েকটি মালিকানাধারী ইউনিক্স বিক্রেতার পসিক্স ১.২-২০০১ এর আগে তাদের শেল পরিবেশ হিমায়িত করে

এই পরীক্ষাটি করার পোর্টেবল উপায় রয়েছে তবে আপনাকে ব্যবহার করতে হবে tr:

[ "x`printf '%s' "$var" | tr -d "$IFS"`" = x ]

( $IFSসুবিধামত, এর ডিফল্ট মান হল একটি স্থান, একটি ট্যাব এবং একটি নতুন লাইন)

( printfবিল্টিনটি নিজেই স্পষ্টতই বহনযোগ্য, তবে আপনার কোন রূপটি রয়েছে তা নির্ধারণের চেয়ে এর উপর নির্ভর করা কম ঝামেলা echo)


1
এটি কিছুটা বিশৃঙ্খলাবদ্ধ। একটি স্ট্রিং নির্দিষ্ট অক্ষর রয়েছে কিনা পরীক্ষা করার জন্য স্বাভাবিক পোর্টেবল উপায় সঙ্গেcase
গিলস

@ গিলস আমি মনে করি না যে caseশূন্যস্থানটি ফাঁকা রয়েছে বা তার মধ্যে কেবল শ্বেত স্পেসের অক্ষর রয়েছে তা সনাক্ত করার জন্য একটি গ্লোব লেখা সম্ভব । (এটা কোন RegExp সঙ্গে সহজ হতে পারে, কিন্তু caseregexps করে না যদি আপনি নতুন লাইন যত্নশীল আপনার উত্তর কনস্ট্রাক্ট কাজ করবে না।।)
zwol

1
আমি আমার উত্তরে উদাহরণ হিসাবে ফাঁকা স্থান দিয়েছি কারণ এটাই প্রশ্নটি চেয়েছিল। এটা তোলে হোয়াইটস্পেস অক্ষরের জন্য পরীক্ষা করার জন্য সমানভাবে সহজ: case $param in *[![:space:]]*) …। আপনি যদি IFSঅক্ষরের জন্য পরীক্ষা করতে চান তবে আপনি প্যাটার্নটি ব্যবহার করতে পারেন *[$IFS]*
গিলস

1
@ মিমক্জার্ভস একটি সত্যই গুরুতর প্রতিরক্ষামূলক স্ক্রিপ্টে আপনি স্পষ্টভাবে আইএফএস <space><tab><newline>শুরুতে সেট করেছেন এবং তারপরে আবার কখনও স্পর্শ করবেন না। আমি ভেবেছিলাম যে এটি একটি ব্যাঘাত হবে।
zwol

1
নিদর্শনগুলিতে পরিবর্তনশীলগুলি সম্পর্কে, আমি মনে করি যে সমস্ত বোর্ন সংস্করণ এবং সমস্ত পসিক্স শেলগুলিতে কাজ করে; কেস প্যাটার্নগুলি সনাক্ত করতে এবং পরিবর্তনশীল প্রসারণ বন্ধ করতে এটির জন্য অতিরিক্ত কোডের প্রয়োজন হবে এবং আমি এটি করার কারণটি ভাবতে পারি না। আমার কাছে এর বেশ কয়েকটি উদাহরণ রয়েছে .profileযা বহু বোর্ন শেল দ্বারা কার্যকর করা হয়েছিল। অবশ্যই নির্দিষ্ট অ-ডিফল্ট মান (খালি (বা আনসেট) থাকা, থাকে বা এর সাথে শুরু করে ) থাকলে [$IFS]তা যা করা হবে তা করবে না । IFS]!^
গিলস

4
if [[ -n "${variable_name/[ ]*\n/}" ]]
then
    #execute if the the variable is not empty and contains non space characters
else
    #execute if the variable is empty or contains only spaces
fi

এটি কোনও একক স্থান নয়, কোনও সাদা স্থানের অক্ষর থেকে মুক্তি পেয়েছে? ধন্যবাদ
আলেকজান্ডার মিলস

0

ভেরিয়েবলটি ফাঁকা থাকলে বা ফাঁকা স্থান রয়েছে কিনা পরীক্ষার জন্য আপনি এই কোডটিও ব্যবহার করতে পারেন:

${name:?variable is empty}

2
আমি মনে করি আপনার উত্তরটি নিম্নচঞ্চিত হয়েছে কারণ "বা স্পেস থাকা" সত্য নয়।
বার্নহার্ড

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

কিভাবে এটি শেল মারা হবে। এবং আপনি এটিও পরীক্ষা করে দেখতে পারেন, প্রথমে সংজ্ঞা দিন name=aaaaতারপর এটি চালান echo ${name:?variable is empty}এটি ভেরিয়েবল নামের মান প্রিন্ট করবে এবং এখন এই কমান্ডটি চালাবে echo ${name1:?variable is empty}এটি প্রিন্ট করবে -sh: name1: ভেরিয়েবলটি খালি আছে
প্রতীক

হ্যাঁ - echo ${name:?variable is empty}পারেন নির্ণয় করা হবে $name'র অ নাল মান বা এটা শেল মেরে ফেলবে। সুতরাং একই কারণে আপনি prompt > $randomvarনা করা উচিত নয় ${var?}- যদি সেখানে কোনও কমান্ড থাকে তবে সম্ভবত এটি চালানো যেতে পারে - এবং এটি কী তা আপনি জানেন না। একটি ইন্টারেক্টিভ শেলটি প্রস্থান করতে হবে না - এজন্য আপনারটি না। তবুও, আপনি যদি কিছু পরীক্ষা দেখতে চান তবে এখানে অনেকগুলি রয়েছে এটি বেশ দীর্ঘ নয় ...
মাইক্রোসার্ভ

0

কোনও ভেরিয়েবলটি সেট না করা থাকলে খালি (একটি নাল মান রয়েছে ) বা কেবল স্থান রয়েছে:

 [ -z "${param#"${param%%[! ]*}"}" ] && echo "empty"

ব্যাখ্যা:

  • ${param%%[! ]*}প্রথম অ-স্থান থেকে শেষ পর্যন্ত অপসারণের প্রসারণ ।
  • যে শুধুমাত্র নেতৃস্থানীয় স্পেস ছেড়ে।
  • পরবর্তী সম্প্রসারণটি ভেরিয়েবল থেকে নেতৃস্থানীয় স্পেসগুলি সরিয়ে দেয়।
  • যদি ফলাফলটি খালি হয়, তবে ভেরিয়েবলটি শুরুতে খালি ছিল।
  • অথবা, যদি ভেরিয়েবলটি খালি না থাকে তবে নেতৃস্থানীয় স্থানগুলি সরিয়ে ফেললে এটি খালি হয়ে যায়।
  • ফলাফলটি ফাঁকা থাকলে -zপ্রতিধ্বনিত হয় empty

উপরেরটি পসিক্স সামঞ্জস্যপূর্ণ এবং কোনও বোর্নের বংশধরদের মধ্যে চলছে।

আপনি যদি এটি ট্যাবগুলিতেও প্রসারিত করতে চান তবে একটি স্পষ্ট ট্যাব অন্তর্ভুক্ত করুন:

 [ -z "${param#"${param%%[!     ]*}"}" ] && echo "empty"

বা আপনার মুছে ফেলা প্রয়োজন এমন অক্ষরগুলির সাথে একটি ভেরিয়েবল ব্যবহার করুন:

 var=$' \t'   # in ksh, bash, zsh
 [ -z "${param#"${param%%[!$var]*}"}" ] && echo "empty"

অথবা আপনি কিছু POSIX "অক্ষর শ্রেণীর এক্সপ্রেশন" ব্যবহার করতে পারেন (ফাঁকা মানে স্থান এবং ট্যাব):

 [ -z "${param#"${param%%[![:blank:]]*}"}" ] && echo "empty"

তবে তা মক্ষ, লক্ষ এবং পশিতে ব্যর্থ হবে।


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