ক্ষেত্র বিভাজনের জন্য আমি কখন অস্থায়ী আইএফএস ব্যবহার করতে পারি?


19

ব্যাশে, বলুন আপনার কাছে রয়েছে var=a.b.c., তারপরে:

$ IFS=. printf "%s\n" $var
a.b.c

যাইহোক, IFSঅ্যারে তৈরি করার সময় এরকম ব্যবহার কার্যকর হয়:

$ IFS=. arr=($var)
$ printf "%s\n" "${arr[@]}"
a
b
c

এটি খুব সুবিধাজনক, নিশ্চিত, তবে এই নথিটি কোথায়? বাশ ডকুমেন্টেশনে অ্যারে বা ওয়ার্ড স্প্লিটিংয়ের বিভাগগুলির দ্রুত পড়া কোনওভাবেই ইঙ্গিত দেয় না। একক পৃষ্ঠার ডকুমেন্টেশনেরIFS মাধ্যমে অনুসন্ধান কোনও ক্ষেত্রে এই প্রভাব সম্পর্কে কোনও ইঙ্গিত সরবরাহ করে না।

আমি কখনই নির্ভরযোগ্যভাবে করতে পারি তা নিশ্চিত নই:

IFS=x do something

এবং আশা করি এটি IFSফিল্ড বিভাজনকে প্রভাবিত করবে।

উত্তর:


28

মূল ধারণাটি হ'ল কখন বাহ্যিক কমান্ড হয় তা কার্যকর করার জন্য VAR=VALUE some-commandসেট VARকরে এবং এটি এর চেয়ে বেশি অভিনবতা পায় না। শেল কীভাবে কাজ করে তার কিছু জ্ঞানের সাথে যদি আপনি এই স্বজ্ঞাতকে একত্রিত করেন তবে বেশিরভাগ ক্ষেত্রে আপনার সঠিক উত্তরটি নিয়ে আসা উচিত। POSIX রেফারেন্স "সহজ কমান্ড" অধ্যায়ে "শেল কমান্ড ভাষা"VALUEsome-commandsome-command

যদি some-commandএকটি হয় বহিরাগত কমান্ড , VAR=VALUE some-commandসমতূল্য env VAR=VALUE some-commandVARএর পরিবেশে রফতানি করা হয় some-command, এবং শেলের মধ্যে এর মান (বা কোনও মানের অভাব) পরিবর্তন হয় না।

যদি some-commandকোনও ফাংশন হয় তবে VAR=VALUE some-commandতার সমতুল্য VAR=VALUE; some-commandঅর্থাত ফাংশন ফিরে আসার পরে অ্যাসাইনমেন্টটি স্থানে থাকে এবং ভেরিয়েবলটি পরিবেশে রফতানি হয় না। এর কারণ বোর্ন শেলটির নকশা (এবং পরবর্তীকালে পশ্চাদপদ সামঞ্জস্য সহ) এর সাথে সম্পর্কিত: এটির কোনও কার্য সম্পাদনের চারপাশে পরিবর্তনশীল মানগুলি সংরক্ষণ এবং পুনরুদ্ধার করার কোনও সুবিধা ছিল না। ভেরিয়েবল রফতানি না করা অর্থহীন হয়ে যায় যেহেতু কোনও ফাংশন শেল নিজেই চালায়। তবে, ksh (উভয় এটিটি ksh93 এবং pdksh / mksh সহ), ব্যাশ এবং zsh আরও কার্যকর আচরণ বাস্তবায়িত করে যেখানে VARকেবল ফাংশন সম্পাদনের সময় সেট করা হয় (এটিও রফতানি হয়)। ইন ksh , এই যদি ফাংশন ksh সিনট্যাক্স সঙ্গে সংজ্ঞায়িত করা হয় সম্পন্ন করা হয়function NAME …না, যদি এটি স্ট্যান্ডার্ড সিনট্যাক্সের সাথে সংজ্ঞায়িত হয় NAME ()। ইন ব্যাশ , এই শুধুমাত্র ব্যাশ মোড মধ্যে সম্পন্ন করা হয়, POSIX মোডে নেই (যখন দিয়ে চালানো POSIXLY_CORRECT=1)। ইন zsh , এই যদি সম্পন্ন করা হয় posix_builtinsবিকল্প সেট না করা হয়; এই বিকল্পটি ডিফল্ট হিসাবে সেট করা হয়নি তবে এটি দ্বারা emulate shবা চালু করা আছে emulate ksh

যদি some-commandবিল্টিন হয় তবে আচরণটি বিল্টিনের ধরণের উপর নির্ভর করে। বিশেষ বিল্টিনগুলি ফাংশনের মতো আচরণ করে। বিশেষ বিল্ট-ইনগুলি সেইগুলি যা শেলের ভিতরে প্রয়োগ করতে হয় কারণ তারা রাষ্ট্রের শেলকে প্রভাবিত করে (যেমন breakনিয়ন্ত্রণের প্রবাহকে cdপ্রভাবিত করে, বর্তমান ডিরেক্টরিকে প্রভাবিত করে, setঅবস্থানগত পরামিতি এবং বিকল্পগুলিকে প্রভাবিত করে ...)। অন্যান্য বিল্টিনগুলি কেবল পারফরম্যান্স এবং সুবিধার জন্য অন্তর্নির্মিত হয় (বেশিরভাগ - যেমন ব্যাশ বৈশিষ্ট্যটি printf -vকেবল কোনও বিল্টিন দ্বারা প্রয়োগ করা যেতে পারে) এবং তারা বাহ্যিক আদেশের মতো আচরণ করে।

অ্যাসাইনমেন্টটি ওরফে প্রসারণের পরে সংঘটিত হয়, সুতরাং যদি some-commandকোনও উপাধি হয় তবে কী ঘটে তা সন্ধান করার জন্য প্রথমে এটি প্রসারিত করুন।

নোট করুন যে সমস্ত ক্ষেত্রে, কমান্ড লাইনটি পার্স করার পরে অ্যাসাইনমেন্টটি সম্পাদন করা হয়, কমান্ড লাইনেই কোনও পরিবর্তনশীল বিকল্প সহ। সুতরাং var=a; var=b echo $varপ্রিন্টগুলি a, কারণ $varঅ্যাসাইনমেন্ট হওয়ার আগে মূল্যায়ন করা হয়। এবং এইভাবে বিভক্ত করতে IFS=. printf "%s\n" $varপুরানো IFSমান ব্যবহার করে $var

আমি সমস্ত ধরণের কমান্ড কভার করেছি, তবে আরও একটি কেস রয়েছে: যখন কার্যকর করার জন্য কোনও কমান্ড নেই , অর্থাত্ যদি কমান্ডটি কেবলমাত্র কার্যনির্বাহী (এবং সম্ভবত পুনর্নির্দেশগুলি) নিয়ে থাকে। সেক্ষেত্রে, নিয়োগ জায়গায় রয়েVAR=VALUE OTHERVAR=OTHERVALUEসমতূল্য VAR=VALUE; OTHERVAR=OTHERVALUE। সুতরাং পরে IFS=. arr=($var), IFSসেট সেট .। যেহেতু আপনি ইতিপূর্বে এর নতুন মান রয়েছে এমন প্রত্যাশার সাথে $IFSআপনি অ্যাসাইনমেন্টটিতে ব্যবহার করতে পারেন তাই arrএটি উপলব্ধি করে যে এর নতুন মানটি IFSপ্রসারণের জন্য ব্যবহৃত হয় $var

সংক্ষেপে, আপনি কেবল অস্থায়ী ক্ষেত্র বিভাজনের IFSজন্য ব্যবহার করতে পারেন :

  • একটি নতুন শেল বা একটি সাবশেল শুরু করার মাধ্যমে (উদাহরণস্বরূপ third=$(IFS=.; set -f; set -- $var; echo "$3")একটি জটিল পদ্ধতি third=${var#*.*.}ব্যতীত তারা যখন অন্যরকম আচরণ করে তখন এর মান varদুটি .অক্ষরের কম থাকে );
  • ksh এ, IFS=. some-functionযেখানে some-functionksh সিনট্যাক্সের সাথে সংজ্ঞায়িত করা হয়েছে function some-function …;
  • ব্যাশ এবং জেডএসে, IFS=. some-functionযতক্ষণ না তারা নেটিভ মোডে অপারেটিং চলছে ততক্ষণ সঙ্গতি মোডের বিপরীতে।

" IFSEec এ সেট থাকা ."। প্রথম অংশটি পড়ার পরে, এটি বোঝা যায়, তবে আমি এই প্রশ্নটি পোস্ট করার আগে, আমি এটি আশা করি না।
মুরু

1
এটি একটি পৃথক প্রশ্নের উত্তর
21

কয়েক বছর আগে থেকে এই উত্তরে কিছু অতিরিক্ত ব্যাখ্যা ।
তি স্টারগা

6

@ গিলসের উত্তর সত্যই দুর্দান্ত, তিনি একটি জটিল বিষয় (বিশদভাবে) ব্যাখ্যা করেছেন।

তবে, আমি বিশ্বাস করি যে এই আদেশটির উত্তর:

$ IFS=. printf "%s\n" $var
a.b.c

এটি যেমন কাজ করে তেমন সহজ ধারণাটি হ'ল পুরো কমান্ড লাইনটি কার্যকর হওয়ার আগে পার্স করা হয়। এবং প্রতিটি "শব্দ" শেল দ্বারা একবার প্রক্রিয়া করা হয়। বরাদ্দকরণ, মত , বিলম্বিত হয় (পদক্ষেপ 4 শেষ এক):
IFS=.

৪.- প্রতিটি পরিবর্তনশীল দায়িত্ব বাড়ানো হবে ...

কমান্ড কার্যকর হওয়ার আগে এবং আর্গুমেন্টের সমস্ত বিস্তৃতকরণ কার্যকর করার আগে এই নির্বাহযোগ্য লাইনটি তৈরি করার আগে প্রক্রিয়া করা হয়:

$ IFS=. printf "%s\n" a.b.c           ## IFS=. goes to the environment.
a.b.c

এর মান $varথেকে 'পুরানো' IFS সঙ্গে প্রসারিত হয় a.b.cকমান্ড সামনে printfআর্গুমেন্ট দেওয়া হয় "%s\n"এবং a.b.c

Eval

এক স্তরের বিলম্ব এর দ্বারা প্রবর্তিত হতে পারে eval:

$ IFS=. eval printf "'%s\n'" \$var
a
b
c

লাইনটি পার্স করা হয়েছে (প্রথমবার) এবং 'আইএফএস ='। পরিবেশ হিসাবে এই হিসাবে সেট করা হয়:

$ printf '%s\n' $var

তারপরে এটি আবার বিশ্লেষণ করা হয়েছে:

$ printf '%s\n' a b c

এবং এটি কার্যকর করা:

a
b
c

এর মান $var(এবিসি) ব্যবহারে IFS মান বিভক্ত হল: .

পরিবেশ

জটিল এবং কৌতুকপূর্ণ অংশটি যখন পরিবেশে কার্যকর হয় তখন !!!

গিলস উত্তরের প্রথম অংশে এটি খুব ভালভাবে ব্যাখ্যা করা হয়েছে।

একটি অতিরিক্ত বিশদ সহ।

যখন এই আদেশটি কার্যকর করা হয়:

$ IFS=. arr=($var)

আইএফএসের মান বর্তমান পরিবেশে ধরে রাখা হয়, হ্যাঁ:

$ printf '<%s>  ' "${arr[@]}" "$IFS"
<a>  <b>  <c>  <.> 

একক বিবৃতি জন্য আইএফএস।

তবে এটি এড়ানো যায়: একক বিবৃতি দেওয়ার জন্য আইএফএস সেট করা

$ IFS=. command eval arr\=\(\$var\)

$  printf '<%s>  ' "${arr[@]}" "$IFS"
<a>  <b>  <c>  < 
> 

2

আপনার প্রশ্ন সম্পর্কিত

var=a.b.c
IFS=. printf "%s\n" $var

একটি কোণার কেস।

এর কারণ শেল ভেরিয়েবল সেট macro expansionহওয়ার আগে কমান্ড ইন - ইন হয় IFS=.

অন্য কথায়: যখন $varপ্রসারিত হয়, পূর্বের IFSমানটি সক্রিয় হয়, তারপরে IFSসেট করা থাকে '.'

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