বাশ স্ক্রিপ্টে কোনও স্ট্রিং একটি রেজেক্সের সাথে মেলে কিনা তা পরীক্ষা করুন


204

যুক্তি হল যে আমার স্ক্রিপ্ট পায় এক নিম্নলিখিত বিন্যাসে একটি তারিখ: yyyymmdd

আমি ইনপুট হিসাবে কোনও বৈধ তারিখ পাই কিনা তা আমি খতিয়ে দেখতে চাই।

কিভাবে আমি এটি করতে পারব? আমি একটি রেজেক্স ব্যবহার করার চেষ্টা করছি:[0-9]\{\8}


ফর্ম্যাটটি সঠিক কিনা তা পরীক্ষা করা সহজ। তবে আমি মনে করি না যে আপনি ব্যাশে (বিল্ট-ইনগুলি সহ) তারিখটি বৈধ কিনা তা পরীক্ষা করে দেখতে পারেন।
রেডএক্স

উত্তর:


316

আপনি পরীক্ষার নির্মাণ ব্যবহার করতে পারেন, [[ ]]=~ স্ট্রিংটি একটি রেজেক্স প্যাটার্নের সাথে মেলে কিনা তা পরীক্ষা করার জন্য নিয়মিত এক্সপ্রেশন ম্যাচ অপারেটরের সাথে ।

আপনার নির্দিষ্ট ক্ষেত্রে, আপনি লিখতে পারেন:

[[ $date =~ ^[0-9]{8}$ ]] && echo "yes"

বা আরও একটি সঠিক পরীক্ষা:

[[ $date =~ ^[0-9]{4}(0[1-9]|1[0-2])(0[1-9]|[1-2][0-9]|3[0-1])$ ]] && echo "yes"
#           |^^^^^^^^ ^^^^^^ ^^^^^^  ^^^^^^ ^^^^^^^^^^ ^^^^^^ |
#           |   |     ^^^^^^^^^^^^^  ^^^^^^^^^^^^^^^^^^^^^^^^ |
#           |   |          |                   |              |
#           |   |           \                  |              |
#           | --year--   --month--           --day--          |
#           |          either 01...09      either 01..09     end of line
# start of line            or 10,11,12         or 10..29
#                                              or 30, 31

এটি হ'ল, আপনি যে ফর্ম্যাটটি চান তার সাথে মিলে বাশের একটি রেজেক্স নির্ধারণ করতে পারেন can এইভাবে আপনি করতে পারেন:

[[ $date =~ ^regex$ ]] && echo "matched" || echo "did not match"

যেখানে কমান্ড পরে && পরীক্ষা সফল ||হলে কমান্ডগুলি কার্যকর করা হয় এবং পরীক্ষাটি ব্যর্থ হলে কমান্ডগুলি কার্যকর করা হয়।

দ্রষ্টব্য এটি বাশ-এ ব্যবহারকারী ইনপুট তারিখের ফর্ম্যাট যাচাইকরণে আলেকস-ড্যানিয়েল জাকিমেনকোর সমাধানের ভিত্তিতে


অন্যান্য শেলগুলিতে আপনি গ্রেপ ব্যবহার করতে পারেন । যদি আপনার শেলটি পসিক্স অনুগত হয় তবে করুন

(echo "$date" | grep -Eq  ^regex$) && echo "matched" || echo "did not match"

ইন মাছ , যা POSIX-অনুবর্তী নয়, আপনি কি করতে পারেন

echo "$date" | grep -Eq "^regex\$"; and echo "matched"; or echo "did not match"

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

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

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

4
আপভোট, এটি ওপি প্রশ্নের তুলনায় কিছুটা ছাড়িয়ে ব্যবহার করতে দেয়, উদাহরণস্বরূপ,
ডেরিকসন

3
@ Aleks-DanielJakimenko, grep ব্যবহার করা হয় তবে আপনি ব্যবহার করছেন ভাল বিকল্প মনে করা হয় sh, fishবা অন্যান্য কম সজ্জিত শাঁস।
টমেকিভি 3'15

47

বাশ সংস্করণ 3 এ আপনি '= ~' অপারেটরটি ব্যবহার করতে পারেন:

if [[ "$date" =~ ^[0-9]{8}$ ]]; then
    echo "Valid date"
else
    echo "Invalid date"
fi

তথ্যসূত্র: http://tldp.org/LDP/abs/html/bashver3.html#REGEXMATCHREF

দ্রষ্টব্য: ডাবল বন্ধনীগুলির মধ্যে ম্যাচিং অপারেটরের উদ্ধৃতি, [[]], বাশ সংস্করণ ৩.২ অনুসারে আর প্রয়োজন নেই


20
আপনার নিয়মিত প্রসারণে চর ব্যবহার করা উচিত নয়? কারণ আমি যখন এক্সপ্রেসন ব্যবহার করি তখন কাজ হয় না
দাউদ ড্রজড ২

তদ্ব্যতীত, la এবং escap এর ব্যাকস্ল্যাশ পলায়ন একইভাবে সমস্যাযুক্ত।
কুলগ্রিগেন

32

স্ট্রিং সঠিক তারিখ কিনা তা পরীক্ষা করার একটি ভাল উপায় হ'ল কমান্ডের তারিখটি ব্যবহার করা:

if date -d "${DATE}" >/dev/null 2>&1
then
  # do what you need to do with your date
else
  echo "${DATE} incorrect date" >&2
  exit 1
fi

মন্তব্য থেকে: কেউ ফর্ম্যাটিং ব্যবহার করতে পারেন

if [ "2017-01-14" == $(date -d "2017-01-14" '+%Y-%m-%d') ] 

9
আপনার উত্তরকে উচ্চ মানের রেট দিন কারণ এটি তারিখের সাথে তারিখ ফাংশনকে ত্রুটি-প্রবণ রিজেক্সগুলি না করে ডিল করতে দেয়
আলী

ব্রড ডেট বিকল্পগুলি যাচাই করার জন্য এটি ভাল, তবে আপনার যদি নির্দিষ্ট তারিখের ফর্ম্যাটটি যাচাই করতে হয় তবে এটি কি তা করতে পারে? উদাহরণস্বরূপ যদি আমি date -d 2017-11-14eএটি করি মঙ্গল নভেম্বর 14 05:00:00 ইউটিসি 2017 প্রদান করে তবে এটি আমার স্ক্রিপ্টটি ভেঙে দেবে।
জোশিয়ার

1
আপনি এর মতো কিছু ব্যবহার করতে পারেন: ["2017-01-14" == $ (তারিখ -d "2017-01-14" '+% Y-% মি-% ডি')] তারিখটি সঠিক কিনা তা পরীক্ষা করে এবং ফলাফলটি আপনার প্রবেশ করা ডেটার মত একই কিনা তা পরীক্ষা করে দেখুন। যাইহোক, স্থানীয়করণের তারিখের ফর্ম্যাট (উদাহরণস্বরূপ মাস-দিন-বছর বনাম দিন-মাস-বছর) নিয়ে খুব সাবধানতা অবলম্বন করুন
জাজানো জান্নি

1
আপনার লোকেলের উপর নির্ভর করে কাজ করতে পারে না। এমএম-ডিডি-ওয়াইওয়াই ব্যবহার করে আমেরিকান-ফর্ম্যাট করা তারিখগুলি বিশ্বের অন্য কোথাও কাজ করবে না, ডিডি-এমএম-ওয়াইওয়াই (ইউরোপ) বা ওয়াইওয়াই-এমএম-ডিডি (এশিয়ার কয়েকটি জায়গা) ব্যবহার করে
পল

@ পল, কী কাজ করবে না? একটি মন্তব্যে লেখা হিসাবে, কেউ ফর্ম্যাটিং বিকল্পগুলি ব্যবহার করতে পারে ...
বেটলিস্ট

4

আমি এর expr matchপরিবর্তে ব্যবহার করব =~:

expr match "$date" "[0-9]\{8\}" >/dev/null && echo yes

এটি বর্তমানে ব্যবহারের গ্রহণযোগ্য উত্তরের চেয়ে ভাল =~কারণ =~খালি স্ট্রিংগুলির সাথেও মিলবে, যা এটি করা উচিত নয়। ধরুন badvarসংজ্ঞায়িত না করা হয়েছে, তারপরে [[ "1234" =~ "$badvar" ]]; echo $?(ভুলভাবে) দেওয়া হয়েছে 0, যখন expr match "1234" "$badvar" >/dev/null ; echo $?সঠিক ফলাফল দেয় 1

আমরা ব্যবহার করতে হবে >/dev/nullলুকিয়ে রাখবেন তা expr matchএর আউটপুট মান , যা অক্ষরের সংখ্যা সাথে মিল পাওয়া গেছে অথবা 0 যদি কোনো মিল পাওয়া যায়নি। নোট করুন এর আউটপুট মানটি তার প্রস্থান স্থিতি থেকে আলাদা । কোনও মিল খুঁজে পাওয়া গেলে প্রস্থান স্থিতি 0 বা অন্যথায় 1 হয়।

সাধারণত, এর বাক্য গঠনটি exprহ'ল:

expr match "$string" "$lead"

বা:

expr "$string" : "$lead"

যেখানে $leadনিয়মিত প্রকাশ হয়। এটি exit statusযদি সত্য হয় (0) তবে leadশীর্ষস্থানীয় স্লাইসের সাথে মেলে string(এর কোনও নাম আছে?)। উদাহরণস্বরূপ expr match "abcdefghi" "abc"প্রস্থান করে trueতবে বের expr match "abcdefghi" "bcd"হয় false। (এটি দেখানোর জন্য @ কার্লো উডের ক্রেডিট।


7
=~খালি স্ট্রিংয়ের সাথে মেলে না, আপনি যে উদাহরণটি দিয়েছেন তাতে খালি প্যাটার্নের সাথে আপনি একটি স্ট্রিং মেলাচ্ছেন । বাক্য গঠনটি হ'ল string =~ pattern, এবং একটি খালি প্যাটার্ন সবকিছুর সাথে মেলে।
bstpierre

2
এটি একটি স্ট্রিংয়ের সাথে মেলে না, এটি প্রত্যাবর্তন করে (স্টাডআউটে) মিলেছে এমন শীর্ষস্থানীয় অক্ষরের সংখ্যা এবং প্রস্থান স্থিতি সত্য যদি if কমপক্ষে 1 টি অক্ষর মিলেছিল। এই কারণেই একটি খালি স্ট্রিং (যা 0 টি অক্ষরের সাথে মেলে) এর মিথ্যা প্রস্থান স্থিতি রয়েছে। উদাহরণস্বরূপ expr match "abcdefghi" "^" && echo Matched || echo No match- এবং expr match "abcdefghi" "bcd" && echo Matched || echo No match- উভয়ই ফিরে আসে "0\nNo match"। যেখানে ম্যাচিং "a.*f"ফিরে আসবে "6\nMatched"। আপনার উদাহরণে '^' এর ব্যবহার অতএব অপ্রয়োজনীয় এবং ইতিমধ্যে জড়িত।
কার্লো উড

@bstpierre: এখানে মূল বিষয়টি নয় যে কেউ =~খালি স্ট্রিংয়ের সাথে মেলে আচরণের যৌক্তিকাকে বিবেচনা করতে পারে কিনা । এটি এই আচরণটি অপ্রত্যাশিত এবং ত্রুটির কারণ হতে পারে। আমি এই উত্তরটি বিশেষভাবে লিখেছিলাম কারণ এটি দ্বারা আমি পুড়ে গিয়েছিলাম।
পেঙ্গে গেঞ্জ

@ পেঙ্গেজেং অপ্রত্যাশিত আচরণ? যদি কোনও প্যাটার্নের কোনও সংজ্ঞা বা বাধা থাকে না, তবে এটি বাস্তবে কোনও কিছুর সাথে মেলে। প্যাটার্নের অনুপস্থিতি সবকিছুর সাথে মিল। দৃ code় কোডটি লেখার উত্তর, একটি দুর্বল ব্যাখ্যাকে ন্যায়সঙ্গত করা নয়।
অ্যান্টনি রাটলেজ

@ অ্যান্থনিআর্টলজ "রবস্ট কোড" দুর্ঘটনাক্রমে কোডিং ত্রুটি প্রতিরোধের জন্য উপলব্ধ সরঞ্জামগুলির সর্বোত্তম ব্যবহারের দাবি করে। শেল কোডে যেখানে কোনও ফাঁকা ভেরিয়েবল সহজে এবং দুর্ঘটনাক্রমে যেকোন সময় ভুল বানানের মতো উপস্থাপন করা যেতে পারে, আমি মনে করি না যে খালি ভেরিয়েবলগুলি মেলাতে দেওয়া একটি শক্তিশালী বৈশিষ্ট্য। স্পষ্টতই জিএনইউর লেখক exprআমার সাথে একমত হয়েছেন।
পেঙ্গে গেঞ্জ

0

যেখানে একটি রেজেক্সের ব্যবহার কোনও তারিখের চরিত্রের ক্রমটি সঠিক কিনা তা নির্ধারণ করতে সহায়ক হতে পারে, তবে তারিখটি বৈধ কিনা তা নির্ধারণ করার জন্য এটি সহজে ব্যবহার করা যায় না। নিম্নলিখিত উদাহরণগুলি নিয়মিত অভিব্যক্তিটি পাস করবে তবে সমস্ত অবৈধ তারিখগুলি: 20180231, 20190229, 20190431

সুতরাং যদি আপনার তারিখের স্ট্রিংটি (আসুন এটি কল করুন datestr) সঠিক ফর্ম্যাটে থাকে তবে আপনি যদি যাচাই করতে চান তবে এটি দিয়ে পার্স করা ভাল withdate এবং dateস্ট্রিংটিকে সঠিক ফর্ম্যাটে রূপান্তর । যদি উভয় স্ট্রিং অভিন্ন হয় তবে আপনার বৈধ বিন্যাস এবং বৈধ তারিখ রয়েছে।

if [[ "$datestr" == $(date -d "$datestr" "+%Y%m%d" 2>/dev/null) ]]; then
     echo "Valid date"
else
     echo "Invalid date"
fi
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.