বাশ স্ক্রিপ্টিংয়ে আইএফএস = $ '\ n' এর অর্থ কী?


163

ব্যাশ শেল স্ক্রিপ্টের শুরুতে নিম্নলিখিত লাইনটি থাকে:

IFS=$'\n'

প্রতীক সংগ্রহের পেছনের অর্থ কী?


3
এছাড়াও ইউনিক্স.স্ট্যাকেক্সেঞ্জাওয়েজ / প্রশ্নগুলি / ২676784৮ / বোঝাপড়া -আইফস এবং এর উত্সযুক্ত প্রশ্নগুলি দেখুন ।
গিলস

ভিএম সিনট্যাক্স এটিকে আমার জন্য ত্রুটি হিসাবে হাইলাইট করে; ঠিক?
theonlygusti

IFS=$'\n'একটি bashism (+ + অন্যান্য শাঁস হয়, ব্যবহার বরাত দিয়ে ANSI-সি , সমাধান নীচে উপস্থিত দেখতে জন্য stackoverflow.com/questions/10748703/...
pevik

উত্তর:


199

IFSএর অর্থ "অভ্যন্তরীণ ক্ষেত্র বিভাজক"। শেল দ্বারা শব্দ বিভাজন কীভাবে করা যায়, অর্থাত কীভাবে শব্দ সীমা চিহ্নিত করতে হয় তা নির্ধারণ করতে এটি ব্যবহৃত হয়।

বাশের মতো শেলের মধ্যে এটি ব্যবহার করে দেখুন (অন্যান্য শেলগুলি এটিকে অন্যভাবে পরিচালনা করতে পারে, উদাহরণস্বরূপ zsh):

mystring="foo:bar baz rab"
for word in $mystring; do
  echo "Word: $word"
done

ডিফল্ট মানটির জন্য IFSসাদা স্থানের অক্ষর থাকে (সুনির্দিষ্ট হতে হবে: স্থান, ট্যাব এবং নিউলাইন)। প্রতিটি চরিত্র একটি শব্দ সীমানা হতে পারে। সুতরাং, এর ডিফল্ট মান সহ IFS, উপরের লুপটি মুদ্রণ করবে:

Word: foo:bar
Word: baz
Word: rab

অন্য কথায় শেলটি মনে করে যে সাদা স্থান একটি শব্দের সীমানা।

এখন, IFS=:লুপটি কার্যকর করার আগে সেটিংস চেষ্টা করুন । এবার, ফলাফল:

Word: foo
Word: bar baz rab

এখন, শেলটি mystringশব্দগুলিতেও বিভক্ত হয় - তবে এখন, এটি কেবল একটি কোলনকে শব্দের সীমানা হিসাবে বিবেচনা করে।

এর প্রথম চরিত্রটি IFSবিশেষ: এটি বিশেষ $*চলকটি ব্যবহার করার সময় আউটপুটে শব্দগুলি সীমিত করতে ব্যবহৃত হয় (উদাহরণস্বরূপ অ্যাডভান্সড ব্যাশ স্ক্রিপ্টিং গাইড থেকে নেওয়া , যেখানে আপনি এর মতো বিশেষ ভেরিয়েবলের আরও তথ্য পেতে পারেন):

$ bash -c 'set w x y z; IFS=":-;"; echo "$*"'
w:x:y:z

তুলনা করা:

$ bash -c 'set w x y z; IFS="-:;"; echo "$*"'
w-x-y-z

মনে রাখবেন যে, উভয় উদাহরণ এ, শেল এখনও অক্ষরের সব বিবেচনা করবে :, -এবং ;শব্দ সীমানা হিসাবে। একমাত্র যে জিনিসটি পরিবর্তন হয় তা হ'ল আচরণ $*

আর একটি গুরুত্বপূর্ণ বিষয় যা জানা যায় তা হল তথাকথিত "আইএফএস হোয়াইটস্পেস" কীভাবে চিকিত্সা করা হয় । মূলত, IFSশ্বেতস্পেসের অক্ষর অন্তর্ভুক্ত হওয়ার সাথে সাথে, প্রসেসিংয়ের আগে নেতৃস্থানীয় এবং পিছনের শ্বেত স্পেসটি বিভক্ত হওয়ার জন্য স্ট্রিং থেকে ছিনিয়ে নেওয়া হয় এবং ক্রমাগত হোয়াইটস্পেসের অক্ষরের একটি ক্রম ক্ষেত্রগুলিও সীমিত করে দেয়। যাইহোক, এটি কেবল সেই প্রকৃতপক্ষে উপস্থিত শ্বেতস্পেসের অক্ষরের জন্য প্রযোজ্য IFS

উদাহরণস্বরূপ, স্ট্রিং তাকান "a:b:: c d "(trailing স্থান এবং দুটি স্থান অক্ষর cএবং d)।

  1. সঙ্গে IFS=:: এটা চার ক্ষেত্র বিভক্ত করা হবে "a", "b", ""(খালি স্ট্রিং) এবং " c d "(আবার, দুই মধ্যে স্পেস cএবং d)। সর্বশেষ ক্ষেত্রের শীর্ষস্থানীয় এবং চলমান শ্বেত স্পেসটি নোট করুন।
  2. সঙ্গে IFS=' :', এটা পাঁচটি ক্ষেত্র বিভক্ত করা হবে: "a", "b", ""(খালি স্ট্রিং), "c"এবং "d"। কোথাও কোনও শীর্ষস্থানীয় এবং অনুসরণযোগ্য শ্বেতস্পেস নেই।

একাধিক, পরপর শ্বেতস্পেসের অক্ষরগুলি দ্বিতীয় উদাহরণে দুটি ক্ষেত্রের সীমানা নির্ধারণ করুন, যখন একাধিক, একটানা কলোন হয় না (যেহেতু তারা শ্বেতক্ষেত্রের অক্ষর নয়)।

হিসাবে IFS=$'\n', যে একটি হল ksh93এছাড়াও দ্বারা সমর্থিত সিনট্যাক্স bash, zsh, mkshও FreeBSD sh(সমস্ত শাঁস মধ্যে বৈচিত্র সহ)। বাশ ম্যানপেজটি উদ্ধৃত:

ফর্মের শব্দগুলি 'স্ট্রিং' বিশেষভাবে চিকিত্সা করা হয়। শব্দটি "স্ট্রিং" -তে প্রসারিত হয়, ব্যাকস্ল্যাশ-পলায়নযুক্ত অক্ষরগুলি এএনএসআই সি স্ট্যান্ডার্ড দ্বারা নির্দিষ্ট করা হিসাবে প্রতিস্থাপন করা হয়েছিল।

\nএকটি নতুন লাইনের জন্য পলায়ন ক্রম, তাই IFSএকক নিউলাইন চরিত্রে সেট আপ হয়ে যায়।


3
এটি ভাল, তবে আমার মতে আপনি bashস্ক্রিপ্টিং গাইড বা যা-ই হোক না কেন POSIX স্পেকটি পড়তে এবং বুঝতে আরও অনেক ভাল করতে চাই । মূলত, এর মতো লিঙ্কগুলিতে উপলভ্য তথ্যের গুরুত্বপূর্ণ উপায়ে অভাব রয়েছে। যাইহোক, শেল বিভাজন সম্পর্কিত দুটি গুরুত্বপূর্ণ পয়েন্ট মিস করে - গ্লোব্বিং এবং আইএফএস হোয়াইটস্পেস।
মাইকজার্ভ

@ মাইকজার্ভ ধন্যবাদ, আমি আইএফএস হোয়াইটস্পেসে কিছু তথ্য যুক্ত করেছি। সে সম্পর্কে জানতাম না। :)
টিবলু

4
প্রাসঙ্গিক হিসাবে নয়, তবে আপনি যদি কৌতূহলী হন তবে আপনি এটি দেখতে চাইতে পারেন যে unset IFSশেলটি কীভাবে তার থেকে খুব আলাদা আচরণ করে IFS="${named_array[*]}"আইএফএসের প্রথম বাইটটিও বিশেষ বিশেষ - তবে যখন প্রসারটি অনির্বাচিত হয় তখন কোনটিই গুরুত্বপূর্ণ নয় ..
মাইকজার্ভ

আরও কয়েকটি বিষয়: 1- শব্দের বিভাজক, যা নিয়ন্ত্রিত হয় $IFSতালিকার প্রসঙ্গে একটি অব্যক্ত পরিবর্তনশীল প্রসারিত করার পরে সম্পাদিত দুটি প্রধান বিষয়গুলির মধ্যে একটি (এটি অপারেটরের splitঅংশ split+glob)। অন্যটি গ্লোব করছে। কাজের বিভাজন ব্যবহার করার সময়, আপনাকে সাধারণত অংশটি set -fঅক্ষম করতে ইস্যু করতে হবে glob
স্টাফেন চেজেলাস

3
3- $IFSএছাড়াও readবিল্টিন কমান্ড দ্বারা ব্যবহৃত হয়
স্টাফেন চেজেলাস

22

ডোলার্ডযুক্ত একক উদ্ধৃতিগুলির ভিতরে কিছু চরিত্র বিশেষভাবে মূল্যায়ন করা হয়। উদাহরণস্বরূপ, \nনতুন লাইনে অনুবাদ করা হয়।

সুতরাং, এই নির্দিষ্ট লাইনটি ভেরিয়েবল আইএফএসকে নতুন লাইন বরাদ্দ করে। আইএফএস, পরিবর্তে, বাশের একটি বিশেষ পরিবর্তনশীল: অভ্যন্তরীণ ক্ষেত্র বিভাজক। যেমনটি আছে man bash, এটি

শব্দটি বিস্তারের পরে বিভাজন এবং readবিল্টিন কমান্ডের সাহায্যে শব্দগুলিতে লাইনগুলি বিভক্ত করতে ব্যবহৃত হয় । ডিফল্ট মান <space><tab><newline>


5
dollared single quotesসাধারণ একক উদ্ধৃতি থেকে আলাদা যা উল্লেখ করার জন্য +1 ।
তুষারপাত

2
ডলারেড সিঙ্গল কোট উল্লেখ করার জন্য +1 বলার জন্য @ স্নোক্র্যাশ +1 যা সাধারণ একক উদ্ধৃতি থেকে আলাদা । দুঃখিত, এটি সাহায্য করতে পারেনি :) তবে এটি গুরুত্বপূর্ণ কারণ এটি উল্লেখ করা সত্যিই ভাল জিনিস কারণ এটি গুরুত্বপূর্ণ!
প্রাইফটান

1
@ প্রিফটান +1 +1 এর জন্য +1 ... আপনি জানেন ... এটি সত্যই গুরুত্বপূর্ণ।
0xc0de

@ 0xc0de অবশ্যই সম্মত! তার জন্য ধন্যবাদ! :)
প্রাইফটান

15

সংক্ষেপে, ভেরিয়েবলকে IFS=$'\n'নতুন লাইন বরাদ্দ করুন ।\nIFS

$'string'কন্সট্রাক্ট একটি উদ্ধৃতি প্রক্রিয়া যা এএনএসআই সি'কে পালানোর সিকোয়েন্সগুলির মতো ডিকোড করতে ব্যবহার করে। এই সিনট্যাক্স থেকে আসে ksh93, এবং ভালো আধুনিক শেল পোর্টেবল ছিল bash, zsh, pdksh, busybox sh

এই সিনট্যাক্সটি পসিক্স দ্বারা সংজ্ঞায়িত করা হয়নি, তবে এসইএস ইস্যু 7 এর জন্য গৃহীত হয়েছিল ।


-1

আমি $IFSউদাহরণের মাধ্যমে ব্যাখ্যা করতে পছন্দ করলাম :
मानুন আপনি সিপি বা এমভি বা অন্য কোনও ফাইল সংগ্রহ করতে চান, আইএফএস খালি খালি থাকে, যখন আপনার ফাইলগুলির মেটা চর বা স্থান যেমন:
Linux Administration.pdfবা Free Software Fundation.ogg, অবশ্যই আপনার প্রব্লেম হবে, কারণ: লিনাক্স একটি বিবেচনা করে পৃথক পরম এবং প্রশাসক পৃথক পৃথক পরম বিবেচনা করে o সুতরাং বাশ এর built-in variableপরে আপনি আরম্ভ করতে পারেন IFS==$(echo -en "\n\b"), তারপরে ব্যাশ ফাইলের নামের মধ্যে কোনও মেটা চর এবং স্থান ফেলে দেয়, উদাহরণস্বরূপ:

#!/bin/bash
SAVEIFS=$IFS
IFS=$(echo -en "\n\b")
mymusicdir=~/test/dd
find $mymusicdir -name "*" -execdir rename 's/ /_/g' "{}" +
IFS=$SAVEIFS
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.