ব্যাশে স্ট্রিংয়ের দৈর্ঘ্য


428

আপনি একটি ভেরিয়েবলে স্ট্রিংয়ের দৈর্ঘ্য কীভাবে পাবেন এবং এটিকে অন্য ভেরিয়েবলের জন্য নির্ধারণ করবেন?

myvar="some string"
echo ${#myvar}  
# 11

আউটপুটটিতে আপনি কীভাবে অন্য পরিবর্তনশীল সেট করবেন 11?

উত্তর:


270

ইউটিএফ -8 স্ট্রিং দৈর্ঘ্য

ফেডোরকিয়ার সঠিক উত্তর ছাড়াও , আমি স্ট্রিং দৈর্ঘ্য এবং বাইট দৈর্ঘ্যের মধ্যে পার্থক্যটি দেখাতে চাই:

myvar='Généralités'
chrlen=${#myvar}
oLang=$LANG oLcAll=$LC_ALL
LANG=C LC_ALL=C
bytlen=${#myvar}
LANG=$oLang LC_ALL=$oLcAll
printf "%s is %d char len, but %d bytes len.\n" "${myvar}" $chrlen $bytlen

রেন্ডার করবে:

Généralités is 11 char len, but 14 bytes len.

এমনকি আপনি সঞ্চিত চরগুলিতে একবার দেখে নিতে পারেন:

myvar='Généralités'
chrlen=${#myvar}
oLang=$LANG oLcAll=$LC_ALL
LANG=C LC_ALL=C
bytlen=${#myvar}
printf -v myreal "%q" "$myvar"
LANG=$oLang LC_ALL=$oLcAll
printf "%s has %d chars, %d bytes: (%s).\n" "${myvar}" $chrlen $bytlen "$myreal"

উত্তর দেবে:

Généralités has 11 chars, 14 bytes: ($'G\303\251n\303\251ralit\303\251s').

নোট: মতে Isabell কাওয়ান এর মন্তব্য , আমি সেটিং জুড়েছেন $LC_ALLসহ $LANG

একটি যুক্তির দৈর্ঘ্য

তর্ক নিয়মিত ভেরিয়েবল হিসাবে একই কাজ

strLen() {
    local bytlen sreal oLang=$LANG oLcAll=$LC_ALL
    LANG=C LC_ALL=C
    bytlen=${#1}
    printf -v sreal %q "$1"
    LANG=$oLang LC_ALL=$oLcAll
    printf "String '%s' is %d bytes, but %d chars len: %s.\n" "$1" $bytlen ${#1} "$sreal"
}

হিসাবে কাজ করবে

strLen théorème
String 'théorème' is 10 bytes, but 8 chars len: $'th\303\251or\303\250me'

দরকারী printfসংশোধন সরঞ্জাম:

আপনি যদি:

for string in Généralités Language Théorème Février  "Left: ←" "Yin Yang ☯";do
    printf " - %-14s is %2d char length\n" "'$string'"  ${#string}
done

 - 'Généralités' is 11 char length
 - 'Language'     is  8 char length
 - 'Théorème'   is  8 char length
 - 'Février'     is  7 char length
 - 'Left: ←'    is  7 char length
 - 'Yin Yang ☯' is 10 char length

সত্যিই সুন্দর নয় ... এর জন্য, এখানে একটি সামান্য ফাংশন রয়েছে:

strU8DiffLen () { 
    local bytlen oLang=$LANG oLcAll=$LC_ALL
    LANG=C LC_ALL=C
    bytlen=${#1}
    LANG=$oLang LC_ALL=$oLcAll
    return $(( bytlen - ${#1} ))
}

তারপর এখন:

for string in Généralités Language Théorème Février  "Left: ←" "Yin Yang ☯";do
    strU8DiffLen "$string"
    printf " - %-$((14+$?))s is %2d chars length, but uses %2d bytes\n" \
        "'$string'" ${#string} $((${#string}+$?))
  done 

 - 'Généralités'  is 11 chars length, but uses 14 bytes
 - 'Language'     is  8 chars length, but uses  8 bytes
 - 'Théorème'     is  8 chars length, but uses 10 bytes
 - 'Février'      is  7 chars length, but uses  8 bytes
 - 'Left: ←'      is  7 chars length, but uses  9 bytes
 - 'Yin Yang ☯'   is 10 chars length, but uses 12 bytes

দুর্ভাগ্যক্রমে, এটি নিখুঁত নয়!

তবে কিছু অদ্ভুত ইউটিএফ -8 আচরণ যেমন ডাবল-স্পেস চর, শূন্য ব্যবধানযুক্ত অক্ষর, বিপরীতমুখী স্থানচ্যুতি এবং এমন কিছু ছেড়ে গেছে যা এত সহজ হতে পারে না ...

কটাক্ষপাত আছে diffU8test.sh বা diffU8test.sh.txt আরো সীমাবদ্ধতা জন্য।


আমি এই উত্তরটির প্রশংসা করি, কারণ ফাইল সিস্টেমগুলি অক্ষরে নয়, বাইটে নাম সীমাবদ্ধতা আরোপ করে।
GID

1
আপনার LC_ALL = C এবং সম্ভবত অন্যদেরও সেট করতে হবে।
ইসাবেল

1
@ এফ.হৌরি তবে এটি কিছু কম নয় যে কয়েকটি সিস্টেমে আপনার সমাধান কাজ করবে না, কারণ এটি এলসি_এলকে একা ফেলে দেয়। এটি ডেবিয়ান এবং এটির ডেরাইভেটিভগুলির ডিফল্ট ইনস্টলগুলিতে সূক্ষ্মভাবে কাজ করতে পারে তবে অন্যদের ক্ষেত্রে (আর্চ লিনাক্সের মতো) এটি স্ট্রিংয়ের সঠিক বাইট দৈর্ঘ্য দিতে ব্যর্থ হবে।
ইসাবেল কাউয়ান

1
সাধারণ কিছু নেওয়ার জন্য এবং এটিকে
সংশ্লেষিত

2
@ থিসটেলকনোট আমি দুঃখিত, 對不起 কখনও কখনও সহজ ধারণা মাত্র।
এফ। হাউরি

474

কোনও ভেরিয়েবলে স্ট্রিংয়ের দৈর্ঘ্য পেতে, বলুন:

myvar="some string"
size=${#myvar} 

এটি সঠিকভাবে সংরক্ষণ করা হয়েছে তা নিশ্চিত করার জন্য, echoএটি:

$ echo "$size"
11

8
ইউটিএফ -8 স্টিং সহ আপনার স্ট্রিং দৈর্ঘ্য এবং বাইট দৈর্ঘ্য থাকতে পারে। আমার উত্তর দেখুন
এফ। হাউরি

আপনি এটি অন্যান্য প্যারামিটার বিস্তৃতিতেও সরাসরি ব্যবহার করতে পারেন - উদাহরণস্বরূপ এই পরীক্ষায় আমি পরীক্ষা করে যা উপসর্গ $rulenameদিয়ে শুরু হয় $RULE_PREFIX: [ "${rulename:0:${#RULE_PREFIX}}" == "$RULE_PREFIX" ]
টমাস গায়োট-সিওনেস্ট

আপনি একটি বিট অভিব্যক্তি দয়া করে ব্যাখ্যা করুন গেল #myvarএবং {#myvar}?
লারনার ঝাং

1
@ অ্যালারেনডামগুলি বাশ রেফারেন্স ম্যানুয়াল দেখুন → 3.5.3 শেল প্যারামিটার সম্প্রসারণ চালু ${#parameter}: প্যারামিটারের বর্ধিত মানের অক্ষরের দৈর্ঘ্য প্রতিস্থাপিত হয়
ফেডরকিই 'এসও ক্ষতিগ্রস্থ হওয়া বন্ধ করুন'

25

তুমি ব্যবহার করতে পার:

MYSTRING="abc123"
MYLENGTH=$(printf "%s" "$MYSTRING" | wc -c)
  • wc -cবা wc --bytesবাইট গণনাগুলির জন্য = ইউনিকোড অক্ষর 2, 3 বা আরও বেশি বাইট দিয়ে গণনা করা হয়।
  • wc -mবা wc --charsচরিত্রের জন্য গণনা = ইউনিকোডের অক্ষরগুলি একক হিসাবে গণনা করা হয় যতক্ষণ না তারা আরও বাইট ব্যবহার করে।


3
সিরিয়াসলি? একটি পাইপ, একটি সাবশেল এবং তুচ্ছ কিছু জন্য একটি বাহ্যিক কমান্ড?
gniourf_gniourf 21

এটি এমন কিছু হ্যান্ডেল করে mylen=$(printf "%s" "$HOME/.ssh" | wc -c)যেখানে গ্রহণযোগ্য সমাধান ব্যর্থ হয় এবং আপনাকে myvar=$HOME/.sshপ্রথমে প্রয়োজন ।
জে এল পেয়ারেট

23

আমি সবচেয়ে সহজ কেস চেয়েছিলাম, শেষ পর্যন্ত এটি একটি ফলাফল:

echo -n 'Tell me the length of this sentence.' | wc -m;
36

4
।। দুঃখিত সঙ্গী :( এই ব্যাশ ... অভিশপ্ত হাতুড়ি করে একটি পেরেক, বিশেষ করে আপনার থাম্ব সবকিছু দেখতে পাবে না '। আমাকে এই বাক্যের দৈর্ঘ্য বলুন' 36 অক্ষর আছে echo '' | wc -m=> 1। আপনি ব্যবহার করতে হবে চাই -n: echo -n '' | wc -m=> 0... যে ক্ষেত্রে এটি একটি ভাল সমাধান :)
এজেপি

1
সংশোধনীর জন্য ধন্যবাদ! ম্যানুয়াল পৃষ্ঠাটি বলেছেন: -n do not output the trailing newline
দমতেজ

17

আপনি যদি কমান্ড লাইন বা ফাংশন আর্গুমেন্টের সাহায্যে এটি ব্যবহার করতে চান তবে নিশ্চিত করুন যে আপনি এর size=${#1}পরিবর্তে ব্যবহার করছেন size=${#$1}। দ্বিতীয়টিটি আরও সহজাত হতে পারে তবে ভুল বাক্য গঠন।


14
"আপনি <অবৈধ সিনট্যাক্স>" করতে পারবেন না এমন সমস্যাটির অংশটি হ'ল, সেই সিনট্যাক্সটি অবৈধ, পাঠকের অর্থ কী বোঝাতে হবে তা পরিষ্কার নয়। size=${#1}অবশ্যই বৈধ।
চার্লস ডাফি

ঠিক আছে, এটি অপ্রত্যাশিত। আমি জানতাম না যে # 1 এই ক্ষেত্রে $ 1 এর বিকল্প ছিল।
ডিক গের্তিন

16
এটা না। #প্রতিস্থাপন করছে না $- $বাইরের ধনুর্বন্ধনী এখনও প্রসারণ অপারেটর is #দৈর্ঘ্য অপারেটর, সবসময় হয়।
চার্লস ডাফি

আমি এই উত্তরটি স্থির করেছি যেহেতু এটি একটি দরকারী টিপ তবে নিয়মের ব্যতিক্রম নয় - এটি নিয়মটি ঠিক অনুসরণ করে, যেমন @ চার্লসডুফি
জেন হুপার

16

পোস্টটি শুরু হওয়ার জবাবে:

আপনি যদি কমান্ড লাইন বা ফাংশন যুক্তি দিয়ে এটি ব্যবহার করতে চান ...

কোড সহ:

size=${#1}

এমন একটি ক্ষেত্রে থাকতে পারে যেখানে আপনি কেবল একটি শূন্য দৈর্ঘ্যের যুক্তিটি পরীক্ষা করতে চান এবং ভেরিয়েবল সংরক্ষণ করার দরকার নেই no আমি বিশ্বাস করি আপনি এই ধরণের সিনট্যাক্স ব্যবহার করতে পারেন:

if [ -z "$1" ]; then
    #zero length argument 
else
    #non-zero length
fi

জিএনইউ দেখুন এবং বাশ শর্তসাপেক্ষ এক্সপ্রেশনগুলির আরও সম্পূর্ণ তালিকার জন্য ওয়াজ করুন


11

আপনার দেওয়া উদাহরণ ব্যবহার করে

#KISS (Keep it simple stupid)
size=${#myvar}
echo $size

9

ভেরিয়েবলের দৈর্ঘ্য গণনা করার কয়েকটি উপায় এখানে রয়েছে:

echo ${#VAR}
echo -n $VAR | wc -m
echo -n $VAR | wc -c
printf $VAR | wc -m
expr length $VAR
expr $VAR : '.*'

এবং ফলাফলটি অন্য ভেরিয়েবলে সেট করতে কেবল উপরের কমান্ডটি ব্যাক কোট সহ অন্য ভেরিয়েবলের সাথে নিম্নলিখিত হিসাবে নির্ধারণ করুন:

otherVar=`echo -n $VAR | wc -m`   
echo $otherVar

http://techopsbook.blogspot.in/2017/09/how-to-find-length-of-string-variable.html

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