আমি কীভাবে বাশে কোনও রেগেক্সের সাথে একটি স্ট্রিং মেলাতে পারি?


166

আমি একটি ব্যাশ স্ক্রিপ্ট সুতরাং যখন একটি প্রদত্ত একটি ফাংশন রয়েছে সেটা লিখতে চেষ্টা করছি .tar, .tar.bz2, .tar.gzইত্যাদি ফাইল এটি প্রাসঙ্গিক সুইচ সঙ্গে আলকাতরা ব্যবহার ফাইল ডিকম্প্রেস করতে।

আমি যদি এলিফ ব্যবহার করি তবে ফাইলগুলির নামটি কী দিয়ে শেষ হয় তা পরীক্ষা করে এমন বিবৃতি দেয় এবং আমি রেজেক্স মেটাচ্যাকার্টার ব্যবহার করে এটি মিলাতে পারি না।

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

test sed-4.2.2.tar.bz2 = tar\.bz2$; echo $?
(this returns 1, false)

আমি নিশ্চিত যে সমস্যাটি একটি সহজ সমস্যা এবং আমি সর্বত্র দেখেছি, তবে কীভাবে এটি করব তা আমি বুঝতে পারি না। কেউ কি জানেন যে আমি এটি কীভাবে করতে পারি?

উত্তর:


268

রেজিক্সগুলির সাথে মেলে তুলতে আপনাকে =~অপারেটরটি ব্যবহার করতে হবে ।

এটা চেষ্টা কর:

[[ sed-4.2.2.tar.bz2 =~ tar.bz2$ ]] && echo matched

বিকল্পভাবে, আপনি ==অপারেটরের সাথে ওয়াইল্ডকার্ডগুলি (রেজেক্সের পরিবর্তে) ব্যবহার করতে পারেন :

[[ sed-4.2.2.tar.bz2 == *tar.bz2 ]] && echo matched

যদি বহনযোগ্যতা কোনও উদ্বেগ না হয় তবে আমি এর [[পরিবর্তে [বা testএটি নিরাপদ এবং আরও শক্তিশালী হিসাবে ব্যবহার করার পরামর্শ দিই । দেখুন পরীক্ষার মধ্যে পার্থক্য কী, [এবং [[? বিস্তারিত জানার জন্য.


7
দ্বিতীয় উদাহরণে গ্লোব ওয়াইল্ডকার্ডের ম্যাচিংয়ের সাথে সতর্ক থাকুন। [[]] এর ভিতরে, * বর্তমানের ডিরেক্টরি হিসাবে একটি ফাইলের সাথে মেলে যা সাধারণত: যেমন হয় তেমন প্রসারিত হয় না our কোন প্রসঙ্গ। এটি কেবল [[]] অভ্যন্তরের মতো কাজ করে। অন্যথায়, এটি বিদ্যমান ফাইলের নামগুলিতে প্রসারিত হয়।
অ্যালান পোর্টার

7
আমি রেজেক্সে উদ্ধৃতিগুলি ব্যবহার করার চেষ্টা করেছি এবং ব্যর্থ হয়েছি; এই উত্তরটি এই কাজটি check="^a.*c$";if [[ "abc" =~ $check ]];then echo match;fiকরতে সাহায্য করেছে আমাদের একটি ভারতে রেগেক্স সংরক্ষণ করতে হবে
কুম্ভ শক্তি

এছাড়াও মনে রাখবেন যে রেজিএক্সএক্স (পার্লের মতো) অবশ্যই প্রথম বন্ধনে থাকা উচিত নয়: [[ sed-4.2.2.tar.bz2 == "*tar.bz2" ]]কাজ করবে না।
পেভিক

18
এফডাব্লুআইডাব্লু, উপেক্ষার সিনট্যাক্স (যেমন মেলে না ) [[ ! foo =~ bar ]]
স্কিপি লে গ্র্যান্ড গৌরূ

1
ড্যাশ -n 1প্যারামিটার সমর্থন করে না, এটি এটিকে স্বয়ংক্রিয়ভাবে কোনও $REPLYভেরিয়েবলে রাখে না। সতর্ক থেকো!

54

এটি করার একটি ফাংশন

extract () {
  if [ -f $1 ] ; then
      case $1 in
          *.tar.bz2)   tar xvjf $1    ;;
          *.tar.gz)    tar xvzf $1    ;;
          *.bz2)       bunzip2 $1     ;;
          *.rar)       rar x $1       ;;
          *.gz)        gunzip $1      ;;
          *.tar)       tar xvf $1     ;;
          *.tbz2)      tar xvjf $1    ;;
          *.tgz)       tar xvzf $1    ;;
          *.zip)       unzip $1       ;;
          *.Z)         uncompress $1  ;;
          *.7z)        7z x $1        ;;
          *)           echo "don't know '$1'..." ;;
      esac
  else
      echo "'$1' is not a valid file!"
  fi
}

অন্যান্য নোট

উপরের মন্তব্যে অ্যাকুরিয়াস পাওয়ারের জবাবে, We need to store the regex on a var

আপনার অভিব্যক্তিটি মিলে যাওয়ার পরে চলকটি BASH_REMATCH সেট করা হবে এবং $ AS BASH_REMATCH [n] parent পের্থেসিসে আবৃত নবম গ্রুপের সাথে মিলবে অর্থাৎ নিম্নলিখিত ${BASH_REMATCH[1]} = "compressed"এবং${BASH_REMATCH[2]} = ".gz"

if [[ "compressed.gz" =~ ^(.*)(\.[a-z]{1,5})$ ]]; 
then 
  echo ${BASH_REMATCH[2]} ; 
else 
  echo "Not proper format"; 
fi

(উপরের রেজেক্সটি ফাইলের নামকরণ এবং এক্সটেনশনের জন্য কোনও বৈধ নয়, তবে এটি উদাহরণের জন্য কাজ করে)


এছাড়াও নোট করুন যে বিএসডি টারের সাহায্যে আপনি সমস্ত ফর্ম্যাটের জন্য "টার এক্সএফ" ব্যবহার করতে পারেন এবং আলাদা কমান্ড বা এই ফাংশন যা প্রয়োজন তা দরকার নেই।
ভাল ব্যক্তি

apএক্সটেনশান থেকে স্বয়ংক্রিয়ভাবে সংক্ষেপণের ধরণ নির্ধারণ করতে GNU ট্যারে বা BSD ট্যারে স্পষ্টভাবে তা বলতে। জিএনইউ টর অন্যথায় এটি স্বয়ংক্রিয়ভাবে করবে না এবং আমি গুডপারসনের মন্তব্য থেকে অনুমান করছি যে বিএসডি টার এটি ডিফল্টরূপে করে।
কে কে কোয়ান

7z আনপ্যাক করতে পারে .. এআর, আরজে, সিএবি, সিএইচএম, সিপিআইও, ক্রামএফএস, ডিএমজি, এক্সটি, ফ্যাট, জিপিটি, এইচএফএস, আইএইচএক্স, আইএসও, এলজেডএইচ, এলজেডএমএ, এমবিআর, এমএসআই, এনএসআইএস, এনটিএফএস, কিউসিডাব্লু 2, আরএআর, আরপিএম, স্কোয়াশএফএস , ইউডিএফ, ইউইএফআই, ভিডিআই, ভিএইচডি, ভিএমডিকে, ডাব্লুআইএম, এক্সএআর এবং জেড। দেখুন 7-zip.org
মোশ

14

আমার এখানে মন্তব্য করার মতো পর্যাপ্ত প্রতিনিধি নেই, তাই কুকুরের উত্তরটির উন্নতির জন্য আমি একটি নতুন উত্তর জমা দিচ্ছি। বিন্দু। regexp এ

[[ sed-4.2.2.tar.bz2 =~ tar.bz2$ ]] && echo matched

প্রকৃতপক্ষে কোনও অক্ষরের সাথে মিলবে, উদাহরণস্বরূপ কেবল 'tar.bz2' এর মধ্যে আক্ষরিক বিন্দু নয়

[[ sed-4.2.2.tar4bz2 =~ tar.bz2$ ]] && echo matched
[[ sed-4.2.2.tar§bz2 =~ tar.bz2$ ]] && echo matched

বা '\' দিয়ে পালানোর দরকার নেই এমন কিছু। কঠোর বাক্য গঠন তখন হওয়া উচিত

[[ sed-4.2.2.tar.bz2 =~ tar\.bz2$ ]] && echo matched

অথবা আপনি আরও কঠোর হতে পারেন এবং পূর্বের বিন্দুটিকে রেজেক্সে অন্তর্ভুক্ত করতে পারেন:

[[ sed-4.2.2.tar.bz2 =~ \.tar\.bz2$ ]] && echo matched

9

আপনি যেহেতু ব্যাশ ব্যবহার করছেন তাই আপনার এটি করার জন্য শিশু প্রক্রিয়া তৈরি করার দরকার নেই। এখানে একটি সমাধান রয়েছে যা এটি পুরোপুরি ব্যাশের মধ্যে সম্পাদন করে:

[[ $TEST =~ ^(.*):\ +(.*)$ ]] && TEST=${BASH_REMATCH[1]}:${BASH_REMATCH[2]}

ব্যাখ্যা: "কোলন এবং এক বা একাধিক স্পেস" সিক্যুয়েন্সের আগে এবং পরে গ্রুপগুলি BASH_REMATCH অ্যারেতে প্যাটার্ন ম্যাচ অপারেটর দ্বারা সংরক্ষণ করা হয়।


1
নোট করুন যে সূচক 0-তে পুরো ম্যাচ এবং সূচক 1 এবং 2 এর সাথে গ্রুপের ম্যাচ রয়েছে।
রাইনার শোয়ার্জে

3
if [[ $STR == *pattern* ]]
then
    echo "It is the string!"
else
    echo "It's not him!"
fi

আমার জন্য কাজ কর! GNU bash, version 4.3.11(1)-release (x86_64-pc-linux-gnu)


1
এটি অত্যন্ত বিপজ্জনক; এটি কেবল আপনার জন্য অপরিজ্ঞাত আচরণ ছাড়াই আচরণ করে কারণ আপনার বর্তমান ডিরেক্টরিতে কোনও আক্ষরিক সাবস্ট্রিং "প্যাটার্ন" নামক ফাইল নেই। এগিয়ে যান, এর মতো কিছু ফাইল তৈরি করুন, এবং স্ট্রিংয়ের প্রসারণ ফাইলগুলির সাথে মেলে এবং বহুবিধ রঙের হাইজেনব্যাগগুলির সাথে সবকিছু ভয়াবহভাবে ভেঙে দেবে।
i336_

তবে আমি একটি পরীক্ষা করেছি: বর্তমান ডিরেক্টরিতে pat 1 প্যাটার্ন , প্যাটার্ন প্যাটার্ন 2 এবং প্যাটার্ন সহ। এই স্ক্রিপ্টটি প্রত্যাশার মতো কাজ করে। আপনি কি আমাকে আপনার পরীক্ষার ফলাফলটি সরবরাহ করতে পারেন? @ i336_
জুয়ান

2
@ আই 336: আমি এটি মনে করি না। এর মধ্যে [[ ... ]], আরএইচএস গ্লোব প্যাটার্ন বর্তমান ডিরেক্টরি হিসাবে প্রসারিত হয় না , যেমনটি সাধারণত হয়।
ব্যবহারকারী 1934428

@ i336_ নং এর মধ্যে [[...]], বাশ ফাইল নাম সম্প্রসারণ করবে না। বাশ ম্যানুয়ালটিতে,Word splitting and filename expansion are not performed on the words between the [[ and ]];
জিনবিওম হং

@ জিনবিওমহং: তিল এটা জেনে রাখা ভাল, ধন্যবাদ!
i336_

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