ব্যাশ / কাট / স্প্লিট ব্যবহার করে স্ট্রিংয়ের অংশটি বের করুন


121

আমার মতো স্ট্রিং রয়েছে:

/var/cpanel/users/joebloggs:DNS9=domain.com

আমার joebloggsএই স্ট্রিংটি থেকে ব্যবহারকারীর নাম ( ) বের করতে এবং এটি একটি ভেরিয়েবলে সংরক্ষণ করতে হবে।

বাদে স্ট্রিংটির ফর্ম্যাটটি সর্বদা একই হবে joebloggsএবং domain.comতাই আমি ভাবছি স্ট্রিংটি দু'বার ব্যবহার করে দু'বার ভাগ করা যায় cut?

প্রথম বিভাজন দ্বারা বিভক্ত হবে :এবং আমরা দ্বিতীয় বিভক্ত ফাংশনটি পাস করার জন্য প্রথম অংশটি একটি ভেরিয়েবলের মধ্যে সংরক্ষণ করব।

দ্বিতীয় বিভাজকটি বিভক্ত হয়ে /শেষ শব্দটি ( joebloggs) একটি ভেরিয়েবলে সংরক্ষণ করবে

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

উত্তর:


332

joebloggsকোনও অতিরিক্ত প্রক্রিয়া ছাড়াই প্যারামিটার সম্প্রসারণ ব্যবহার করে ব্যাশটিতে এই স্ট্রিং থেকে নিষ্কাশন করতে ...

MYVAR="/var/cpanel/users/joebloggs:DNS9=domain.com" 

NAME=${MYVAR%:*}  # retain the part before the colon
NAME=${NAME##*/}  # retain the part after the last slash
echo $NAME

joebloggsপথে কোনও নির্দিষ্ট গভীরতায় যাওয়ার উপর নির্ভর করে না ।


সারসংক্ষেপ

রেফারেন্সের জন্য কয়েকটি প্যারামিটার সম্প্রসারণ মোডগুলির একটি ওভারভিউ ...

${MYVAR#pattern}     # delete shortest match of pattern from the beginning
${MYVAR##pattern}    # delete longest match of pattern from the beginning
${MYVAR%pattern}     # delete shortest match of pattern from the end
${MYVAR%%pattern}    # delete longest match of pattern from the end

সুতরাং #শুরু থেকে ম্যাচ মানে (কোনও মন্তব্য লাইনের কথা ভাবেন) এবং এর %অর্থ শেষ থেকে। একটি উদাহরণের অর্থ সংক্ষিপ্ততম এবং দুটি উদাহরণের অর্থ দীর্ঘতম।

আপনি সংখ্যা ব্যবহার করে অবস্থানের ভিত্তিতে সাবস্ট্রিংগুলি পেতে পারেন:

${MYVAR:3}   # Remove the first three chars (leaving 4..end)
${MYVAR::3}  # Return the first three characters
${MYVAR:3:5} # The next five characters after removing the first 3 (chars 4-9)

আপনি ব্যবহার করে নির্দিষ্ট স্ট্রিং বা নিদর্শনগুলি প্রতিস্থাপন করতে পারেন:

${MYVAR/search/replace}

patternফাইল-নাম ম্যাচিং হিসাবে একই বিন্যাসে, তাই *(যে কোন অক্ষর) সাধারণ, প্রায়ই মত একটি নির্দিষ্ট প্রতীক দ্বারা অনুসরণ /বা.

উদাহরণ:

মত একটি ভেরিয়েবল দেওয়া

MYVAR="users/joebloggs/domain.com" 

ফাইলের নামটি ছেড়ে যাওয়ার পথ (একটি স্ল্যাশ পর্যন্ত সমস্ত অক্ষর) সরান:

echo ${MYVAR##*/}
domain.com

পথ ছেড়ে ফাইলের নামটি সরিয়ে ফেলুন (শেষের পরে সংক্ষিপ্ততম মিলটি মুছুন /):

echo ${MYVAR%/*}
users/joebloggs

কেবলমাত্র ফাইলের এক্সটেনশন পান (শেষ সময়ের আগে সমস্ত মুছে ফেলুন):

echo ${MYVAR##*.}
com

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

NAME=${MYVAR##*/}      # remove part before last slash
echo ${NAME%.*}        # from the new var remove the part after the last period
domain

আমি নিশ্চিত এই জন্য অথবা, grep সৃজনশীল ব্যবহারের বিরুদ্ধে একটি আর্গুমেন্ট, কিন্তু VAR = / এখানে / হয় / একটি / পথ সঙ্গে এটি চেষ্টা করে দেখুন: সঙ্গে / A / কোলন / ভিতরে: DNS9 = domain.com
rici

2
খুব সুন্দর! এবং এটি এক্সিকিউটিভ শেলের ভিতরে সম্পন্ন হয়, যার ফলে অন্যান্য কমান্ডগুলি ব্যবহার করার চেয়ে দ্রুততর হয়।
stolvik

3
@ ফাদি আপনাকে কোলনের আগে আসতে ওয়াইল্ডকার্ড পরিবর্তন করতে #হবে এবং তার পরিবর্তে ব্যবহার করতে হবে %। আপনি খুব গত কোলন পরে অংশ মাত্র চান, ব্যবহার ${MYVAR##*:}প্রথম কোলন, ব্যবহার অংশ পেতে${MYVAR#*:}
beroe

4
বন্ধু, আপনি জানেন না যে আমি এই উত্তরে কতবার ফিরে এসেছি। ধন্যবাদ!
জোয়েল বি

1
দুর্দান্ত উত্তর! প্রশ্ন: আমার প্যাটার্নটি যদি ভেরিয়েবল হয় তবে আমি কি এটি টাইপ করব ${RET##*$CHOP}বা এই জাতীয় ${RET##*CHOP}(বা অন্য কোনওভাবে)? সম্পাদনা: প্রাক্তন বলে মনে হচ্ছে,${RET##*$CHOP}
Ctrl এস

43

এটির মতো একটি কার্য নির্ধারণ করুন:

getUserName() {
    echo $1 | cut -d : -f 1 | xargs basename
}

এবং প্যারামিটার হিসাবে স্ট্রিং পাস:

userName=$(getUserName "/var/cpanel/users/joebloggs:DNS9=domain.com")
echo $userName

1
এই উত্তরটি আমাকে এখানে কী জন্য এসেছিল তা অর্জনে সহায়তা করেছে। কোনও গ্রহণযোগ্য উত্তর নেই এবং এটি সরলতার জন্য আমার ভোট পায়।
হার্পারভিলি

1
এই মত: শুধুমাত্র সংশোধন আমি উপরের কমান্ডে কি ছিল সরানোর ছিল '' echo $1 | cut -d -f 1 | xargs। সহজ এবং ঝরঝরে উত্তরগুলির জন্য +1।
ভূষণ

20

সেড কি? এটি একটি একক আদেশে কাজ করবে:

sed 's#.*/\([^:]*\).*#\1#' <<<$string
  • #পরিবর্তে Regex মতে বিভক্ত তাদের জন্য ব্যবহার করা হচ্ছে /যেহেতু স্ট্রিং হয়েছে /তাতে।
  • .*/ শেষ ব্যাকস্ল্যাশ পর্যন্ত স্ট্রিং ধরে gra
  • \( .. \)একটি ক্যাপচার গ্রুপ চিহ্নিত করে। এই \([^:]*\)
    • [^:]একটি কোলন _except কোনো চরিত্র বলেছেন, *মানে শূন্য বা তার বেশি।
  • .* লাইনের বাকি অংশ
  • \1মানে প্রথম (এবং কেবল) ক্যাপচার গ্রুপে যা পাওয়া গেছে তার বিকল্প হ'ল। এই নাম।

নিয়মিত অভিব্যক্তির সাথে স্ট্রিংয়ের মিল রয়েছে এখানে ব্রেকডাউন:

        /var/cpanel/users/           joebloggs  :DNS9=domain.com joebloggs
sed 's#.*/                          \([^:]*\)   .*              #\1       #'

সুপার সুন্দর বিচ্ছিন্নতা!
কেব


10

একটি একক ওক ব্যবহার:

... | awk -F '[/:]' '{print $5}'

তা হল, ফিল্ড বিভাজক হিসাবে /বা হয় হিসাবে ব্যবহার করা: ব্যবহারকারীর নামটি সর্বদা ফিল্ড 5 এ থাকে।

এটি একটি ভেরিয়েবলে সঞ্চয় করতে:

username=$(... | awk -F '[/:]' '{print $5}')

এর সাথে আরও নমনীয় প্রয়োগের sedজন্য ব্যবহারকারীর নামটি ফিল্ড 5 হতে হবে না:

... | sed -e s/:.*// -e s?.*/??

এটি হ'ল, এখান থেকে ওপারে সমস্ত কিছু মুছুন :এবং তারপরে শেষ অবধি সমস্ত কিছু মুছুন /sedসম্ভবত খুব দ্রুত awk, তাই এই বিকল্পটি অবশ্যই ভাল।

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