উত্তর:
আরও সাধারণ সমাধান হতে আপডেট উত্তর। আরো দেখুন নীচের আমার অন্য উত্তর শুধুমাত্র শেল বক্রবন্ধনী বিস্তার এবং ব্যবহার pritnf
।
$ str='Hello World!'
$ sed -r ':loop; s/ (=*):$/\1=:/; t loop' <<< "$(printf '%-20s:\n' "$str" )"
Hello World!========:
কিভাবে এটা কাজ করে?
এটি (=*):$/
একটি স্থান দখল করে, এক বা একাধিক =
যা :
তার ইনপুটটির শেষে একটি কোলন অনুসরণ করে ; আমরা =
একটি গ্রুপ ম্যাচ হিসাবে সেট তৈরি এবং \1
এটির ব্যাক-রেফারেন্স হবে।
সঙ্গে :loop
আমরা একটি লেবেল নামে সংজ্ঞায়িত loop
এবং t loop
এটা সেই লেবেল একটি ঝাঁপ হবে s/ (=*):$/\1=:/
সফল প্রতিস্থাপন করেছেন;
এর সাথে প্রতিস্থাপনের অংশে \1=:
এটি সর্বদা =
s এর সংখ্যা বাড়িয়ে দেবে এবং কোলনটি নিজেই স্ট্রিংয়ের শেষে ফিরে আসবে।
filler='===================='
string='foo'
printf '%s\n' "$string${filler:${#string}}"
দেয়
foo=================
${#string}
মান দৈর্ঘ্য হল $string
, এবং ${filler:${#string}}
এর সাবস্ট্রিং হয় $filler
অফসেট থেকে ${#string}
অগ্রে।
আউটপুট এর মোট প্রস্থ হবে সর্বোচ্চ $filler
বা এর প্রস্থের $string
।
ফিলার স্ট্রিং, সিস্টেমগুলিতে jot
, গতিশীলভাবে ব্যবহার করে তৈরি করা যেতে পারে
filler=$( jot -s '' -c 16 '=' '=' )
( =
এক লাইনে 16 এর জন্য )। জিএনইউ সিস্টেমগুলি ব্যবহার করতে পারে seq
:
filler=$( seq -s '=' 1 16 | tr -dc '=' )
অন্যান্য সিস্টেমগুলি পার্ল বা গতিশীলভাবে স্ট্রিং তৈরির কিছু দ্রুত উপায় ব্যবহার করতে পারে।
printf
ফিল্টারটি প্রায় সমস্ত সিস্টেমে পাওয়া যায় এবং শাঁসের সাথে ব্রেস প্রসারিত হয় তা কেন জেনারেট না করে bash/szh
?
printf
+ ব্রেস সম্প্রসারণের মাধ্যমে করবেন bash
?
printf "%.20s:\n\n" "$str========================="
%.20s
স্ট্রিং কাটানো বিন্যাসটি কোথায়
এটি করার একটি উপায়:
printf "====================:\r%s\n\n" 'hello world!!'
====================\rhello world
যা ওপিকে এটি কেবল স্ক্রিনে মুদ্রণ না করে প্রয়োজন হলে এটি একটি সমস্যা হতে পারে।
echo -e '=================\rHello World!!'
, তবে @ ইটারডন ইঙ্গিত করে বলে একই সমস্যা রয়েছে।
echo
সমর্থন করে -e
। printf
প্রায় সবসময়ই echo
অনেক কারণের চেয়ে ভাল ।
একটি পার্ল পদ্ধতির:
$ perl -le '$k="hello world!!"; while(length($k)<20){$k.="=";} print "$k\n"'
hello world!!=======
বা আরও ভাল, @ স্যাটোক্যাটসুরা মন্তব্যগুলিতে উল্লেখ করেছেন:
perl -le '$k = "hello world!!"; print $k, "=" x (20-length $k), "\n"'
আপনার যদি ইউটিএফ মাল্টি-বাইট অক্ষর সমর্থন করার প্রয়োজন হয়, ব্যবহার করুন:
PERL_UNICODE='AS' perl -le '$k = "hello world!!"; print $k, "=" x (20-length $k), "\n"'
শেলের মধ্যে একই ধারণা:
v='hello world!!'; while [ ${#v} -lt 20 ]; do v="$v""="; done; printf '%s\n\n' "$v"
perl -le '$k = "hello world!!"; print $k, "=" x (20-length $k), "\n"'
। তবে মাল্টি-বাইট অক্ষর জড়িত থাকলে এটি (এবং এখনও অবধি পোস্ট হওয়া সমস্ত সমাধান) ব্রেক হয়ে যায়।
perl6
করি এটি মাল্টি-বাইট অক্ষর সহ সঠিকভাবে করার একটি উপায় থাকতে পারে। তবে অন্যদিকে perl6
অনেক উপায়ে বিরক্তিকর।
PERL_UNICODE='AS'
। উদাহরণস্বরূপ: printf '%s' nóóös | perl -nle 'print length($_)'
8 ("ভুল") printf '%s' nóóös | PERL_UNICODE='AS' perl -nle 'print length($_)'
প্রিন্ট করে 5 টি ("সঠিক") প্রিন্ট করে।
অন্য উপায়টি কেবল printf
কমান্ড ব্যবহার করে প্রথমে অক্ষর প্যাডিং প্যাটার্ন তৈরি করে Shell Brace Expansion
(আপনি মুদ্রণ করতে চান এমন একটি সংখ্যা ≥ ফর্ম্যাটিং এরিয়া দিয়ে শেষ করতে পারেন {1..end}
) এবং কেবলমাত্র প্রতিটি প্রথম অক্ষর %.1s
যা =
s এবং তারপরে কেবল প্রথম 20 অক্ষরের দৈর্ঘ্য মুদ্রণ করুন যে অঞ্চল %.20s
। অক্ষরের পরিবর্তে বারবার অক্ষর / শব্দ রাখার এটি এক ধরণের ভাল উপায়।
printf '%.20s:\n' "$str$(printf '%.1s' ={1..20})"
Hello World!!=======:
ব্যাখ্যা:
সাধারণত ব্রেস এক্সপেনশন হিসাবে শেল প্রসারিত {1..20}
হয় যদি আমরা সেগুলি প্রিন্ট করি তবে নীচে হিসাবে শেল প্রসারিত হবে ।
printf '%s ' {1..20}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
এটিতে একটি সমান চিহ্ন যোগ করার সাথে সাথে ={1..20}
শেলটি নিম্নলিখিত হিসাবে প্রসারিত হবে।
printf '%s ' ={1..20}
=1 =2 =3 =4 =5 =6 =7 =8 =9 =10 =11 =12 =13 =14 =15 =16 =17 =18 =19 =20
এবং printf '%.1s'
যা আসলে মাধ্যম printf '%WIDE.LENGTH'
, আমরা কেবল এক মুদ্রণ করছে LENGTH এর ডিফল্ট সাথে উপরে এ ঐ 1
ওয়াইড । সুতরাং কেবলমাত্র ফলাফল হবে =
এবং 20 বার নিজেই পুনরাবৃত্তি হবে।
এখন printf '%.20s:\n'
আমরা কেবল 20 দৈর্ঘ্য $str
এবং $str
<20 দৈর্ঘ্যের প্রিন্ট করছি , বাকী =
স্থানগুলি পরিবর্তে উত্পন্ন এস থেকে নেওয়া হবে ।