চতুর্থাংশ 1। মাঠ বিভাজন।
ক্ষেত্র বিভাজন শব্দের বিভাজন হিসাবে একই?
হ্যাঁ, উভয়ই একই ধারণাটির প্রতি নির্দেশ দেয়।
IFS=''
নাল হিসাবে একই সেট করা , খালি স্ট্রিংয়ের মতোও?
হ্যাঁ, তিনটিই একই অর্থ: কোনও ক্ষেত্র / শব্দ বিভাজন করা হবে না। এছাড়াও, এটি মুদ্রণ ক্ষেত্রগুলিকে প্রভাবিত করে (যেমন হিসাবে echo "$*"
) সমস্ত ক্ষেত্র কোনও স্থান ছাড়াই একত্রিত হবে।
Q3: (অংশ ক) আনসেট আইএফএস।
পসিএক্স স্পেসিফিকেশনে আমি নিম্নলিখিতটি পড়ি :
যদি আইএফএস সেট না করা থাকে তবে শেলটি এমন আচরণ করবে যেন আইএফএসের মান <স্পেস ><tab> <নিউলাইন> ।
যা হুবহু:
একটি unset IFS
দিয়ে শেলটি এমন আচরণ করবে যেন আইএফএস ডিফল্ট থাকে।
তার মানে 'ডিফল্ট আইএফএস মান, বা আনসেট না করে' ফিল্ড বিভাজন 'হুবহু একই রকম হবে।
এর অর্থ এই নয় যে আইএফএস সমস্ত পরিস্থিতিতে একইভাবে কাজ করবে। আরো নির্দিষ্ট হচ্ছে, নির্বাহ OldIFS=$IFS
Var সেট হবে OldIFS
থেকে নাল , ডিফল্ট না। এবং আইএফএসকে পিছনে সেট করার চেষ্টা করা হচ্ছে, IFS=OldIFS
এটি আইএফএসকে বাতিল করে দেবে, আগের মতো সেট না করে রাখবে। সতর্ক থেকো !!.
Q3: (অংশ খ) আইএফএস পুনরুদ্ধার করুন।
আমি কীভাবে আইএফএসের মান ডিফল্টে পুনরুদ্ধার করতে পারি। বলুন আমি আইএফএসের ডিফল্ট মানটি পুনরুদ্ধার করতে চাই। আমি কেমন করে ঐটি করি? (আরও সুনির্দিষ্টভাবে, আমি কীভাবে <ট্যাব> এবং <নিউলাইন> উল্লেখ করব ?)
Zsh, ksh, এবং bash (AFAIK) এর জন্য আইএফএসকে ডিফল্ট মান হিসাবে সেট করা যেতে পারে:
IFS=$' \t\n' # works with zsh, ksh, bash.
হয়ে গেল, আপনাকে আর কিছু পড়তে হবে না।
তবে sh এর জন্য আপনার যদি আইএফএস পুনরায় সেট করতে হয় তবে এটি জটিল হয়ে উঠতে পারে।
আসুন কোনও অসুবিধা (জটিলতা ব্যতীত) সম্পূর্ণ করার জন্য সহজ থেকে এক নজরে নেওয়া যাক।
1.- আনসেট আইএফএস।
আমরা কেবল unset IFS
(উপরে Q3 অংশ একটি পড়ুন।)।
2.- চরগুলি অদলবদল।
কার্যকারণ হিসাবে, ট্যাব এবং নিউলাইনটির মান অদলবদল করা আইএফএসের মান সেট করা আরও সহজ করে তোলে এবং তারপরে এটি সমান উপায়ে কাজ করে।
আইএফএসকে <স্পেস> << নিউলাইন> <ট্যাব> এ সেট করুন :
sh -c 'IFS=$(echo " \n\t"); printf "%s" "$IFS"|xxd' # Works.
3.- একটি সরল? সমাধান:
যদি এমন কোনও শিশু স্ক্রিপ্ট থাকে যা আইএফএসের সঠিকভাবে সেট করা থাকে তবে আপনি সর্বদা ম্যানুয়ালি লিখতে পারেন:
IFS = '
'
যেখানে ম্যানুয়ালি টাইপ করা ক্রমটি ছিল:, IFS=
'spacetabnewline'ক্রমটি যা আসলে উপরে উপরে সঠিকভাবে টাইপ করা হয়েছে (আপনার যদি নিশ্চিত করার প্রয়োজন হয় তবে এই উত্তরটি সম্পাদনা করুন)। তবে আপনার ব্রাউজারের একটি অনুলিপি / পেস্ট বিচ্ছিন্ন হয়ে যাবে কারণ ব্রাউজারটি সাদা জায়গা স্পর্শ করবে / গোপন করবে। উপরে লিখিতভাবে কোড ভাগ করে নেওয়া কঠিন করে তোলে।
4.- সম্পূর্ণ সমাধান।
সুরক্ষিতভাবে অনুলিপি করা যায় এমন কোডটি লিখতে সাধারণত অসম্পূর্ণ মুদ্রণযোগ্য পলায়ন জড়িত।
আমাদের এমন কিছু কোড দরকার যা প্রত্যাশিত মানটি "উত্পাদন" করে। তবে, ধারণাটি সঠিক হলেও, এই কোডটি কোনও পূর্ববর্তী সেট করবে না \n
:
sh -c 'IFS=$(echo " \t\n"); printf "%s" "$IFS"|xxd' # wrong.
এটি ঘটে কারণ বেশিরভাগ শাঁসের নীচে, বিস্তৃত হওয়ার পরে সমস্ত অনুসরণযোগ্য নিউলাইনগুলি $(...)
বা `...`
কমান্ডের বিকল্পগুলি সরানো হয়।
Sh এর জন্য আমাদের একটি কৌশল ব্যবহার করা দরকার :
sh -c 'IFS="$(printf " \t\nx")"; IFS="${IFS%x}"; printf "$IFS"|xxd' # Correct.
বিকল্প উপায়টি হ'ল বাফ (উদাহরণস্বরূপ) থেকে পরিবেশগত মান হিসাবে আইএফএস সেট করা এবং তারপরে sh কল (এটির সংস্করণগুলি যা আইএফএসকে পরিবেশের মাধ্যমে সেট করার জন্য স্বীকৃতি দেয়) এইভাবে কল করুন:
env IFS=$' \t\n' sh -c 'printf "%s" "$IFS"|xxd'
সংক্ষেপে, sh আইএফএসকে পুনরায় সেট করার পক্ষে বেশ একটি বিজোড় অ্যাডভেঞ্চার।
Q4: আসল কোডে:
শেষ পর্যন্ত, এই কোডটি কীভাবে হবে:
while IFS= read -r line
do
echo $line
done < /path_to_text_file
আমরা যদি প্রথম লাইনে পরিবর্তন করি তবে আচরণ করুন
while read -r line # Use the default IFS value
অথবা:
while IFS=' ' read -r line
প্রথম: আমি জানি না echo $line
(বর্ণিত উদ্ধৃতি সহ) পার্পাউসটিতে আছে কি নেই। এটি 'ফিল্ড বিভাজন' এর দ্বিতীয় স্তরের পরিচয় করিয়ে দেয় যা পঠনযোগ্য নয়। সুতরাং আমি উভয় জবাব দেব। :)
এই কোড সহ (যাতে আপনি নিশ্চিত করতে পারেন)। আপনার দরকারী এক্সএক্সডি প্রয়োজন হবে :
#!/bin/ksh
# Correctly set IFS as described above.
defIFS="$(printf " \t\nx")"; defIFS="${defIFS%x}";
IFS="$defIFS"
printf "IFS value: "
printf "%s" "$IFS"| xxd -p
a=' bar baz quz '; l="${#a}"
printf "var value : %${l}s-" "$a" ; printf "%s\n" "$a" | xxd -p
printf "%s\n" "$a" | while IFS='x' read -r line; do
printf "IFS --x-- : %${l}s-" "$line" ;
printf "%s" "$line" |xxd -p; done;
printf 'Values quoted :\n' "" # With values quoted:
printf "%s\n" "$a" | while IFS='' read -r line; do
printf "IFS null quoted : %${l}s-" "$line" ;
printf "%s" "$line" |xxd -p; done;
printf "%s\n" "$a" | while IFS="$defIFS" read -r line; do
printf "IFS default quoted : %${l}s-" "$line" ;
printf "%s" "$line" |xxd -p; done;
unset IFS; printf "%s\n" "$a" | while read -r line; do
printf "IFS unset quoted : %${l}s-" "$line" ;
printf "%s" "$line" |xxd -p; done;
IFS="$defIFS" # set IFS back to default.
printf "%s\n" "$a" | while IFS=' ' read -r line; do
printf "IFS space quoted : %${l}s-" "$line" ;
printf "%s" "$line" |xxd -p; done;
printf '%s\n' "Values unquoted :" # Now with values unquoted:
printf "%s\n" "$a" | while IFS='x' read -r line; do
printf "IFS --x-- unquoted : "
printf "%s, " $line; printf "%s," $line |xxd -p; done
printf "%s\n" "$a" | while IFS='' read -r line; do
printf "IFS null unquoted : ";
printf "%s, " $line; printf "%s," $line |xxd -p; done
printf "%s\n" "$a" | while IFS="$defIFS" read -r line; do
printf "IFS defau unquoted : ";
printf "%s, " $line; printf "%s," $line |xxd -p; done
unset IFS; printf "%s\n" "$a" | while read -r line; do
printf "IFS unset unquoted : ";
printf "%s, " $line; printf "%s," $line |xxd -p; done
IFS="$defIFS" # set IFS back to default.
printf "%s\n" "$a" | while IFS=' ' read -r line; do
printf "IFS space unquoted : ";
printf "%s, " $line; printf "%s," $line |xxd -p; done
আমি পাই:
$ ./stackexchange-Understanding-IFS.sh
IFS value: 20090a
var value : bar baz quz -20202062617220202062617a20202071757a2020200a
IFS --x-- : bar baz quz -20202062617220202062617a20202071757a202020
Values quoted :
IFS null quoted : bar baz quz -20202062617220202062617a20202071757a202020
IFS default quoted : bar baz quz-62617220202062617a20202071757a
IFS unset quoted : bar baz quz-62617220202062617a20202071757a
IFS space quoted : bar baz quz-62617220202062617a20202071757a
Values unquoted :
IFS --x-- unquoted : bar, baz, quz, 6261722c62617a2c71757a2c
IFS null unquoted : bar, baz, quz, 6261722c62617a2c71757a2c
IFS defau unquoted : bar, baz, quz, 6261722c62617a2c71757a2c
IFS unset unquoted : bar, baz, quz, 6261722c62617a2c71757a2c
IFS space unquoted : bar, baz, quz, 6261722c62617a2c71757a2c
প্রথম মানটি হ'ল সঠিক মান IFS=
'spacetabnewline'
পরের লাইনটি হ'ল ভার্সের সমস্ত হেক্স মান $a
, এবং প্রতিটি পঠিত কমান্ডকে একটি নতুন লাইন '0 এ' হিসাবে দেওয়া হবে।
পরবর্তী লাইনটি, যার জন্য আইএফএস নাল, কোনও 'ফিল্ড বিভাজন' সম্পাদন করে না, তবে নতুন লাইনটি সরানো হয়েছে (প্রত্যাশার মতো)।
পরবর্তী তিনটি লাইন, যেমন আইএফএসের মধ্যে একটি স্পেস রয়েছে, প্রাথমিক স্পেসগুলি সরিয়ে ফেলুন এবং ভারসাম্যটি বাকী ভারসাম্যে সেট করুন।
শেষ চারটি লাইন দেখায় যে একটি অব্যক্ত ভেরিয়েবল কী করবে। মানগুলি (কয়েকটি) স্পেসে বিভক্ত হবে এবং এটি মুদ্রিত হবে:bar,baz,qux,
IFS
এবং একটি আনসেটIFS
খুব আলাদা। Q4 এর উত্তর আংশিকভাবে ভুল: অভ্যন্তরীণ বিভাজকগুলি এখানে স্পর্শ করা হয় না, কেবল অগ্রণী এবং অনুসরণীয়।