সরল উত্তরটি হ'ল: সমস্ত প্রেরককে একজনকে (প্রথমটিতে) ভেঙে দিন।
এর জন্য একটি লুপ প্রয়োজন (যা কম রান করে)log(N) সময়ের ):
var=':a bc::d ef:#$%_+$$% ^%&*(*&*^
$#,.::ghi::*::' # a long test string.
d=':@!#$%^&*()_+,.' # delimiter set
f=${d:0:1} # first delimiter
v=${var//["$d"]/"$f"}; # convert all delimiters to
: # the first of the delimiter set.
tmp=$v # temporal variable (v).
while
tmp=${tmp//["$f"]["$f"]/"$f"}; # collapse each two delimiters to one
[[ "$tmp" != "$v" ]]; # If there was a change
do
v=$tmp; # actualize the value of the string.
done
যা করার বাকি তা হ'ল একটিতে স্ট্রিংটি সঠিকভাবে বিভক্ত করা ডিলিমিটারের এবং এটি মুদ্রণ:
readarray -td "$f" arr < <(printf '%s%s' "$v"'' "$f")
printf '<%s>' "${arr[@]}" ; echo
set -fআইএফএসের পরিবর্তন বা পরিবর্তন করার দরকার নেই ।
শূন্যস্থান, নিউলাইন এবং গ্লোব অক্ষরের সাথে পরীক্ষিত। সব কাজ. বেশ ধীর (যেমন শেল লুপ হওয়ার আশা করা উচিত)।
তবে কেবল বাশের জন্য (ব্যাটার 4.4 -d++ রিডারারের বিকল্পের কারণে )।
SH
শেল সংস্করণ কোনও অ্যারে ব্যবহার করতে পারে না, কেবলমাত্র অ্যারে উপলব্ধ অবস্থানীয় পরামিতি।
ব্যবহার tr -sকরা মাত্র একটি লাইন (আইএফএস স্ক্রিপ্টে পরিবর্তন হয় না):
set -f; IFS=$f command eval set -- '$(echo "$var" | tr -s "$d" "[$f*]" )""'
এবং এটি মুদ্রণ:
printf '<%s>' "$@" ; echo
এখনও ধীর, তবে বেশি কিছু নয়।
commandবোর্নে কমান্ডটি অবৈধ।
Zsh এ, commandকেবলমাত্র বাহ্যিক কমান্ড কল করে এবং যদি commandব্যবহার করা হয় তবে বিফলকে ব্যর্থ করে তোলে ।
Ksh সালে, এমনকি, আইএফএসের commandমান বিশ্বব্যাপী সুযোগে পরিবর্তিত হয়।
এবং commandবিভাজনকে ম্যাক্স সম্পর্কিত শেলগুলিতে ব্যর্থ করে তোলে (এমএক্সএস, লাক্স, পশ) কমান্ড অপসারণ করা commandকোডটি আরও শেলগুলিতে চালিত করে। তবে: commandঅপসারণটি আইএফএসকে বেশিরভাগ শেলের (ইওাল একটি বিশেষ অন্তর্নির্মিত) ব্য্যাশ (পসিক্স মোড ব্যতীত) এবং ডিফল্টে (কোনও এমুলেশন নয়) মোড ব্যতীত এর মান ধরে রাখতে সক্ষম করে। এই ধারণাটি ডিফল্ট zsh এ কাজ করে বা ছাড়া করা যায় না command।
একাধিক অক্ষর আইএফএস
হ্যাঁ, আইএফএস একাধিক চরিত্রের হতে পারে তবে প্রতিটি চরিত্রই একটি যুক্তি তৈরি করবে:
set -f; IFS="$d" command eval set -- '$(echo "$var" )""'
printf '<%s>' "$@" ; echo
আউটপুট দেবে:
<><a bc><><d ef><><><><><><><><>< ><><><><><><><><><
><><><><><><ghi><><><><><>
বাশ সহ, আপনি commandশব্দটি sh / POSIX অনুকরণে না থাকলে বাদ দিতে পারেন। কমান্ডটি ksh93 এ ব্যর্থ হবে (আইএফএস পরিবর্তিত মান রাখে)। Zsh এ কমান্ড commandzsh সন্ধান করার চেষ্টা করেeval কে বাহ্যিক কমান্ড হিসাবে (যা এটি খুঁজে পায় না) এবং ব্যর্থ হয়।
যা ঘটে তা হ'ল কেবলমাত্র আইএফএস অক্ষর যা একটি ডিলিমিটারে স্বয়ংক্রিয়ভাবে পতিত হয় সেগুলি হ'ল আইএফএস সাদা স্থান।
আইএফএসের একটি স্পেস ক্রমাগত সমস্ত স্থানকে এক জায়গায় নামিয়ে ফেলবে। একটি ট্যাব সমস্ত ট্যাব ধসে যাবে। একটি স্থান এবং একটি ট্যাব ফাঁকা জায়গা এবং / অথবা ট্যাবগুলিকে একটি ডিলিমিটারে ভেঙে দেবে। নিউলাইন দিয়ে ধারণাটি পুনরাবৃত্তি করুন।
বেশ কয়েকটি ডিলিমিটরকে ভেঙে ফেলার জন্য কিছু জাগ্রত করা প্রয়োজন।
ধরে নিই ASCII 3 (0x03) ইনপুটটিতে ব্যবহৃত হয় না var:
var=${var// /$'\3'} # protect spaces
var=${var//["$d"]/ } # convert all delimiters to spaces
set -f; # avoid expanding globs.
IFS=" " command eval set -- '""$var""' # split on spaces.
set -- "${@//$'\3'/ }" # convert spaces back.
Ksh, zsh এবং bash (প্রায় সম্পর্কে) বেশিরভাগ মন্তব্য command এবং আইএফএস) এখনও এখানে প্রয়োগ হয়।
$'\0'পাঠ্য ইনপুটটিতে একটি মান কম সম্ভাব্য হবে তবে ব্যাশ ভেরিয়েবলগুলিতে NULs ( 0x00) থাকতে পারে না ।
একই স্ট্রিং ক্রিয়াকলাপ করার জন্য sh এ কোনও অভ্যন্তরীণ কমান্ড নেই, তাই sh স্ক্রিপ্টগুলির জন্য টিআর একমাত্র সমাধান।