কেবল ব্যাশে, কোনও বাহ্যিক আদেশ নেই:
str="foobarbazblargblurg"
[[ $str =~ ${str//?/(.)} ]]
printf "%s%s%s%s " "${BASH_REMATCH[@]:1}"
বা এক-লাইন পাইপ সংস্করণ হিসাবে:
echo foobarbazblargblurg |
{ IFS= read -r str; [[ $str =~ ${str//?/(.)} ]]; \
printf "%s%s%s%s " "${BASH_REMATCH[@]:1}"; }
এটি যেভাবে কাজ করে তা হ'ল স্ট্রিংয়ের প্রতিটি অক্ষরকে "(।)" তে রূপান্তরিত করে রেগেক্স ম্যাচ এবং ক্যাপচারের জন্য =~
, তারপরে BASH_REMATCH[]
অ্যারে থেকে ক্যাপচার হওয়া এক্সপ্রেশনগুলি কেবল আউটপুট আউটপুট করে , প্রয়োজনীয় হিসাবে গোষ্ঠীভুক্ত করা। শীর্ষস্থানীয় / অনুসরণ / মধ্যবর্তী স্থান সংরক্ষণ করা হয়, "${BASH_REMATCH[@]:1}"
এগুলি বাদ দিতে চারপাশে উদ্ধৃতিগুলি সরান ।
এখানে এটি একটি ফাংশনে আবৃত রয়েছে, কোনও আর্গুমেন্ট না থাকলে এটি তার আর্গুমেন্টগুলি প্রক্রিয়া করবে বা স্টিডিনটি পড়বে:
function fmt4() {
while IFS= read -r str; do
[[ $str =~ ${str//?/(.)} ]]
printf "%s%s%s%s " "${BASH_REMATCH[@]:1}"
done < <( (( $# )) && printf '%s\n' "$@" || printf '%s\n' $(< /dev/stdin) )
}
$ echo foobarbazblargblurg | fmt4
foob arba zbla rgbl urg
সেই অনুসারে বিন্যাসের স্ট্রিং সামঞ্জস্য করতে আপনি সহজেই গণনাটিকে প্যারামিটারাইজ করতে পারেন।
একটি পিছনের স্থান যুক্ত করা হয়, printf
যদি সমস্যা হয় তবে তার পরিবর্তে দুটি ব্যবহার করুন :
printf "%s%s%s%s" "${BASH_REMATCH[@]:1:4}"
(( ${#BASH_REMATCH[@]} > 5 )) && printf " %s%s%s%s" "${BASH_REMATCH[@]:5}"
প্রথম printf
প্রিন্টগুলি ( প্রথম অবধি) প্রথম 4 টি অক্ষর, দ্বিতীয় শর্তসাপেক্ষে গোষ্ঠীগুলিকে পৃথক করার জন্য একটি শীর্ষস্থানীয় স্থান দিয়ে সমস্ত বাকী (যদি থাকে) মুদ্রণ করে। জিরোথ উপাদানটির জন্য অ্যাকাউন্ট 4 হিসাবে নয় এমন 5 টি উপাদানের জন্য পরীক্ষা।
নোট:
printf
এর %c
পরিবর্তে শেল ব্যবহার করা যেতে পারে %s
, %c
(সম্ভবত) অভিপ্রায়টি আরও পরিষ্কার করা হয়েছে, তবে এটি মাল্টি-বাইট অক্ষর নিরাপদ নয়। আপনার বাশের সংস্করণটি যদি সক্ষম হয় তবে উপরের সমস্তটি মাল্টি-বাইট অক্ষর নিরাপদ।
- শেলটি
printf
তার বিন্যাসের স্ট্রিংটি পুনরায় ব্যবহার করে যতক্ষণ না এটি তর্কগুলি শেষ না করে, তাই এটি কেবল একবারে 4 টি আর্গুমেন্ট গাব্বল করে এবং পিছনে যুক্তিগুলি পরিচালনা করে (সুতরাং অন্যান্য উত্তরগুলির মতো এখানে কোনও যুক্তির প্রয়োজন নেই যা তর্কিতভাবে ভুল)
BASH_REMATCH[0]
সম্পূর্ণ মিলিত স্ট্রিং, সুতরাং সূচক 1 থেকে শুরু হওয়া কেবল আউটপুট
printf -v myvar ...
পরিবর্তে একটি ভেরিয়েবল সংরক্ষণ করতে ব্যবহার করুন myvar
(সাধারণ পঠন-লুপ / সাব-শেল আচরণের সাপেক্ষে)
printf "\n"
প্রয়োজনে যোগ করুন
আপনি zsh
যদি match[]
পরিবর্তে অ্যারে ব্যবহার করেন তবে উপরের কাজটি করতে পারেন এবং পুরো ম্যাচের সাথে 0 টি উপাদান রাখে না বলে BASH_REMATCH[]
সমস্ত সূচকে 1 টি বিয়োগ করতে পারেন zsh
।
sed
আমি প্রথমে চেষ্টা করেছি নিজেকে লাথি মারতে।