"আইএফএস" ভেরিয়েবলের মানের উপর নির্ভর করে বাশ তার আচরণ পরিবর্তন করে


18

আমি যখন IFSভেরিয়েবলটিকে একটি স্পেসে সেট করি , bashএকাধিক স্পেসকে একটি স্থান হিসাবে বিবেচনা করে ( myprogramএটি এমন একটি প্রোগ্রাম যা এটি প্রাপ্ত কমান্ড লাইন আর্গুমেন্টগুলি মুদ্রণ করে):

IFS=" "
x="hello   hi   world"
./myprogram $x
argv[1] = hello
argv[2] = hi
argv[3] = world

কিন্তু যখন আমি IFSভেরিয়েবলটি কমাতে সেট করি, তখন bashএকাধিক কমা একটি কমা হিসাবে বিবেচনা করে না:

IFS=","
x="hello,,,hi,,,world"
./myprogram $x
argv[1] = hello
argv[2] = 
argv[3] = 
argv[4] = hi
argv[5] = 
argv[6] = 
argv[7] = world

তা কেন?


কেবলমাত্র রেফারেন্সের জন্য, "আইএফএস" এর অর্থ অভ্যন্তরীণ ক্ষেত্র বিভাজক
pr1268

উত্তর:


21

এটি নথিভুক্ত করা হয় man bash। হোয়াইটস্পেস নয় এমন আইএফএসের কোনও চরিত্রের একক ঘটনা একটি ক্ষেত্রের সীমানা নির্ধারণ করে।

থেকে man bash:

শেলটি আইএফএসের প্রতিটি চরিত্রকে একটি সীমানার হিসাবে বিবেচনা করে এবং ক্ষেত্রের টার্মিনেটর হিসাবে এই অক্ষরগুলি ব্যবহার করে অন্যান্য বিস্তারের ফলাফলগুলিকে শব্দের মধ্যে বিভক্ত করে। যদি IFS সেট করা থাকে না, অথবা তার মান ঠিক <space><tab><newline>, ডিফল্ট, তারপর ক্রমের সাথে <space>, <tab>এবং <newline>শুরুতে এবং পূর্ববর্তী প্রসারণও ফলাফল শেষে উপেক্ষা করা হয়, এবং শুরুতে বা শেষ নয় IFS অক্ষরের কোনো ক্রম সীমানা করে তোলে শব্দ। যদি আইএফএসের ডিফল্ট ব্যতীত অন্য কোনও মান থাকে তবে শব্দের শুরু এবং শেষের দিকে শ্বেতস্পেস অক্ষর স্থান, ট্যাব এবং নিউলাইনটির ক্রমগুলি অগ্রাহ্য করা হয়, যতক্ষণ না হোয়াইটস্পেসের অক্ষর আইএফএসের মান হিসাবে থাকে (কোনও আইএফএস শ্বেত স্পেস অক্ষর) )। আইএফএসের কোনও অক্ষর যা আইএফএস শ্বেতস্পেস নয়, কোনও সংলগ্ন আইএফএস হোয়াইটস্পেস অক্ষর সহ একটি ক্ষেত্রের সীমানা নির্ধারণ করে। আইএফএস সাদা স্থানের অক্ষরের একটি অনুক্রমকেও একটি ডিলিমিটার হিসাবে বিবেচনা করা হয়। যদি আইএফএসের মান নাল হয় তবে কোনও শব্দ বিভাজন ঘটে না। [সামনে জোর দাও.]

উদাহরণ: ক্ষেত্র বিভাজন

যদি আইএফএসের কোনও শ্বেতক্ষেত্রের অক্ষর না থাকে তবে শ্বেত স্পেসটি ক্ষেত্রগুলিতে অন্তর্ভুক্ত করা হবে:

$ ( IFS=',' x='one , two,three'; printf "<%s>\n" $x )
<one >
< two>
<three>

যদি আইএফএসের উভয় ফাঁকা এবং কমা থাকে, তবে ফাঁকা ক্রমগুলি, তার পরে কমা এবং তার পরে ফাঁকা অনুক্রমগুলি একক সীমানা হিসাবে বিবেচিত হবে:

$ ( IFS=' ,' x='one , two,three'; printf "<%s>\n" $x )
<one>
<two>
<three>

কমাগুলির ক্রমগুলি খালি ক্ষেত্রের ক্রম হিসাবে ব্যাখ্যা করা হয়:

$ ( IFS=' ,' x='one,,,two,three'; printf "<%s>\n" $x )
<one>
<>
<>
<two>
<three>

উদাহরণস্বরূপ: শীর্ষস্থানীয় এবং পূর্ববর্তী হোয়াইটস্পেস

যদি আইএফএসের কোনও শ্বেতস্পেস থাকে না, তবে যে কোনও নেতৃস্থানীয় এবং অনুসরণকারী শ্বেতক্ষেত্র ক্ষেত্রগুলিতে রাখা হবে:

$ ( IFS=',' x='  one , two,three  ,'; printf "<%s>\n" $x )
<  one >
< two>
<three  >

যদি আইএফএসে ফাঁকা থাকে, তবে ফাঁকাগুলির কোনও শীর্ষস্থানীয় বা অনুক্রমের ক্রমগুলি সরানো হবে:

$ ( IFS=' ,' x='  one , two,three  ,'; printf "<%s>\n" $x )
<one>
<two>
<three>

হয়তো আরো জোর মূল্য "তাহলে হোয়াইটস্পেস অক্ষর স্থান, ট্যাব, এবং সম্পর্কে newline ক্রমের সাথে, শুরুতে এবং শব্দ শেষে উপেক্ষা করা হয় যতদিন হোয়াইটস্পেস অক্ষর IFS মূল্য হল"
জেফ স্ক্যালার হলেন

@ জেফশালার দুর্দান্ত ধারণা: আমি সবেমাত্র একটি বিভাগ যুক্ত করেছি।
1024


আপনার যদি কিছু হারিয়ে যাওয়া মানগুলির সাথে একটি ট্যাব-বিযুক্ত ফাইল থাকে? অর্থাৎ আপনি চাইছেন না যে ট্যাবগুলির ক্রমগুলি একটি একক ট্যাব হিসাবে বিবেচিত হবে। এছাড়াও, ক্ষেত্রগুলিতে কমা রয়েছে তাই এটি একটি সীমানা হিসাবে ব্যবহার করতে পারে না। অন্য কিছু ডিলিমিটার (ট্যাব নয়) ব্যবহারের একমাত্র সমাধান?
দাভোস

@ ডেভোস একক ট্যাবে ডিলিট প্রতিটি ক্ষেত্রের ডেটার জন্য, অন্যান্য সরঞ্জামগুলি সহজেই এটি পরিচালনা করে যেমন বিকল্প বা এর awkসাথে ব্যবহার করা আরও স্বাভাবিক হতে পারে । অন্যথা, আপনি এর সর্বশেষ সংস্করণটি আছে যদি , আপনি ব্যবহার ক্ষেত্র বিশ্লেষণ করতে সক্ষম হতে পারে সঙ্গে বিকল্প। -F'\t'cutbashreadarray-d$'\t'
1024
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.