FS যখন আইএফএস = পড়ুন..` তে, কেন আইএফএসের কোনও প্রভাব নেই?


12

আমার একেবারে ভুল কিছু হতে পারে, তবে এটি আমার কাছে বিশ্বাসযোগ্য মনে হচ্ছে, প্রাক- করণ / সম্পন্ন তালিকার একটি আদেশ হিসাবে আইএফএসের সেটিংসের কোনও প্রভাব নেই।
বাইরের আইএফএস ( whileকনস্ট্রাক্টের বাইরে ) নীচের স্ক্রিপ্টে প্রদর্শিত সমস্ত উদাহরণগুলিতে বিরাজ করছে ..

এখানে কি হচ্ছে? এই পরিস্থিতিতে আইএফএস কী করে সে সম্পর্কে আমার কী ভুল ধারণা আছে? আমি প্রত্যাশা করেছি অ্যারে-বিভক্ত ফলাফলগুলি "প্রত্যাশিত" কলামে প্রদর্শিত হবে।


#!/bin/bash
xifs() { echo -n "$(echo -n "$IFS" | xxd -p)"; } # allow for null $IFS 
show() { x=($1) 
         echo -ne "  (${#x[@]})\t |"
         for ((j=0;j<${#x[@]};j++)); do 
           echo -n "${x[j]}|"
         done
         echo -ne "\t"
         xifs "$IFS"; echo
}
data="a  b   c"
echo -e "-----   --  -- \t --------\tactual"
echo -e "outside        \t  IFS    \tinside" 
echo -e "loop           \t Field   \tloop" 
echo -e "IFS     NR  NF \t Split   \tIFS (actual)" 
echo -e "-----   --  -- \t --------\t-----"
IFS=$' \t\n'; xifs "$IFS"; echo "$data" | while         read; do echo -ne '\t 1'; show "$REPLY"; done 
IFS=$' \t\n'; xifs "$IFS"; echo "$data" | while IFS=    read; do echo -ne '\t 2'; show "$REPLY"; done 
IFS=$' \t\n'; xifs "$IFS"; echo "$data" | while IFS=b   read; do echo -ne '\t 3'; show "$REPLY"; done
IFS=" ";      xifs "$IFS"; echo "$data" | while         read; do echo -ne '\t 4'; show "$REPLY"; done 
IFS=" ";      xifs "$IFS"; echo "$data" | while IFS=    read; do echo -ne '\t 5'; show "$REPLY"; done 
IFS=" ";      xifs "$IFS"; echo "$data" | while IFS=b   read; do echo -ne '\t 6'; show "$REPLY"; done
IFS=;         xifs "$IFS"; echo "$data" | while         read; do echo -ne '\t 7'; show "$REPLY"; done 
IFS=;         xifs "$IFS"; echo "$data" | while IFS=" " read; do echo -ne '\t 8'; show "$REPLY"; done 
IFS=;         xifs "$IFS"; echo "$data" | while IFS=b   read; do echo -ne '\t 9'; show "$REPLY"; done
IFS=b;        xifs "$IFS"; echo "$data" | while IFS=    read; do echo -ne '\t10'; show "$REPLY"; done
IFS=b;        xifs "$IFS"; echo "$data" | while IFS=" " read; do echo -ne '\t11'; show "$REPLY"; done
echo -e "-----   --  -- \t --------\t-----"

আউটপুট:

-----   --  --   --------       actual   
outside           IFS           inside                assigned   
loop             Field          loop    #              inner
IFS     NR  NF   Split          IFS     #  expected    IFS
-----   --  --   --------       -----   #  ---------  --------
20090a   1  (3)  |a|b|c|        20090a  #                              
20090a   2  (3)  |a|b|c|        20090a  #  |a  b   c|  IFS=
20090a   3  (3)  |a|b|c|        20090a  #  |a  |   c|  IFS=b
20       4  (3)  |a|b|c|        20      #                          
20       5  (3)  |a|b|c|        20      #  |a  b   c   IFS=
20       6  (3)  |a|b|c|        20      #  |a  |   c|  IFS=b
         7  (1)  |a  b   c|             #                          
         8  (1)  |a  b   c|             #  |a|b|c|     IFS=" "
         9  (1)  |a  b   c|             #  |a  |   c|  IFS=b
62      10  (2)  |a  |   c|     62      #  |a  b   c|  IFS=
62      11  (2)  |a  |   c|     62      #  |a|b|c|     IFS=" "
-----   --  --   --------       -----      ---------   -------                        

উত্তর:


17

(দুঃখিত, দীর্ঘ ব্যাখ্যা)

হ্যাঁ, IFSভেরিয়েবলের while IFS=" " read; do …বাকি কোডগুলিতে কোনও প্রভাব নেই।

শেল কমান্ড লাইনে দুটি ভিন্ন ধরণের ভেরিয়েবলের বৈশিষ্ট্য উপস্থিত রয়েছে:

  • শেল ভেরিয়েবল (যা কেবল শেলের মধ্যে বিদ্যমান এবং শেলের স্থানীয় রয়েছে)
  • পরিবেশ পরিবর্তনশীল, যা প্রতিটি প্রক্রিয়া জন্য বিদ্যমান। এগুলি সাধারণত সংরক্ষণ করা হয় fork()এবং exec()তাই শিশু প্রক্রিয়াগুলি তাদের উত্তরাধিকার সূত্রে প্রাপ্ত হয়।

আপনি যখন একটি কমান্ড কল করে:

  A=foo B=bar command

কমান্ডটি এমন পরিবেশের মধ্যে কার্যকর করা হয় যেখানে (পরিবেশ) ভেরিয়েবল Aসেট করা থাকে fooএবং Bসেট করা থাকে bar। কিন্তু এই কমান্ড লাইন দিয়ে, বর্তমান শেল ভেরিয়েবল Aএবং Bবাম হয় অপরিবর্তিত

এটি থেকে পৃথক:

A=foo; B=bar; command

এখানে, শেল ভেরিয়েবল Aএবং Bসংজ্ঞায়িত করা হয় এবং কমান্ড পরিবেশ ভেরিয়েবল Aএবং Bসংজ্ঞায়িত ছাড়াই চালিত হয়। এর মান Aএবং Bথেকে অ্যাক্সেসযোগ্য command

তবে, কিছু শেল ভেরিয়েবল যদি export-ed হয় তবে সংশ্লিষ্ট পরিবেশের ভেরিয়েবলগুলি তাদের নিজ নিজ শেল ভেরিয়েবলের সাথে সিঙ্ক্রোনাইজ করা হয়। উদাহরণ:

export A
export B
A=foo; B=bar; command

এই কোডটা দিয়ে, উভয় শেল ভেরিয়েবল এবং শেল পরিবেশ ভেরিয়েবল সেট করা হয় fooএবং bar। যেহেতু পরিবেশ পরিবর্তনশীলগুলি উপ-প্রক্রিয়াগুলির দ্বারা উত্তরাধিকার সূত্রে প্রাপ্ত, তাই commandতাদের মানগুলিতে অ্যাক্সেস করতে সক্ষম হবে।

আপনার মূল প্রশ্নটিতে ফিরে যেতে, এতে:

IFS='a' read

শুধুমাত্র readপ্রভাবিত হয়। এবং প্রকৃতপক্ষে, এই ক্ষেত্রে, ভেরিয়েবলের readমান সম্পর্কে চিন্তা করে না IFS। এটি IFSকেবল তখনই ব্যবহার করা হয় যখন আপনি লাইনটি বিভক্ত করতে বলেন (এবং বেশ কয়েকটি ভেরিয়েবলগুলিতে সঞ্চিত থাকে) যেমন:

echo "a :  b :    c" | IFS=":" read i j k; \
    printf "i is '%s', j is '%s', k is '%s'" "$i" "$j" "$k"

IFSreadএটি তর্ক যুক্ত না করে ব্যবহৃত হয় না। ( সম্পাদনা করুন: এটি একেবারেই সত্য নয়: IFSইনপুট লাইনের শুরু / শেষে সর্বদা উপস্থিত শ্বেত স্পেস অক্ষর, যেমন স্থান এবং ট্যাব সবসময় উপেক্ষা করা হয়))


কি দুর্দান্ত ব্যাখ্যা! এটা এত সহজ! আমি কয়েক মাস ধরে 'কোনও আধা-কোলন' সিনট্যাক্স দ্বারা বিস্মিত হই ; এবং এটা শুধু এটি একটি কেস একটি স্থানীয় পরিবর্তনশীল, যার অর্থ হয়! .. rozcietrzewiacz আমার (বড়-টাইম) জন্য পথ খোলা অন্য প্রশ্ন ... আর আপনি শুধু পিষ্টক উপর গ্লেজ করা আছে ... আমি চলেছি সারা রাত ধরে এই এক, এবং এই যেমন ভাল এবং পরিষ্কার উত্তর জন্য এটি অবশ্যই মূল্যবান হয়েছে! .. ধন্যবাদ ..
পিটার.ও

UHM। আমার সম্পাদনার মন্তব্যটি পাওয়ার আগে আমাকে বেশ কয়েকবার পড়তে হয়েছিল - আপনি বলতে চাইছেন যে উপস্থিত সাদা $IFSঅংশের অক্ষরগুলি ইনপুট লাইনের শুরু / শেষের দিকে সরিয়ে দেওয়া হয়, আমার ধারণা? (এটি কীভাবে কাজ করে))
zrajm

দয়া করে এটি একবার দেখুন: unix.stackexchange.com

IFS মান হয় গুরুত্বপূর্ণ, এমনকি যখন একটি একক পরিবর্তনশীল পড়া, কারণ শেল এখনও ইনপুটের শব্দ বিভাজন আছে। সুতরাং উদাহরণস্বরূপ, অক্ষর টাইপ a<tab>bমধ্যে read varVar মান পরিণাম ডেকে আনবে a<space>b, কিন্তু এর পরিবর্তে আপনি যদি IFS='<newline>' read varVar মান হতে হবে তারপর a<tab>b
জন হাস্কল

8

এটিকে সহজ ভাষায় বলুন, আপনার উদাহরণ 1 এ কনস্ট্রাক্টের দৃশ্যমান প্রভাব ফেলতে আপনার একবারে একাধিক পরিবর্তনশীল পড়তে হবেIFS=<something> read ...

readউদাহরণগুলিতে আপনি সুযোগটি মিস করেছেন । নেই কোন আপনার পরীক্ষার ক্ষেত্রে লুপ ভিতরে IFS পরিবর্তনের। আমাকে ঠিক নির্দেশ করতে অনুমতি দিন, যেখানে দ্বিতীয় আইএফএসের আপনার প্রতিটি লাইনে এর প্রভাব রয়েছে:

 IFS=$' \t\n'; xifs "$IFS"; echo "$data" | while IFS=b   read; do echo ...
                                                      ^      ^
                                                      |      |
                                          from here --'       `- to here :)

এটি শেলের সাথে সম্পাদিত যে কোনও প্রোগ্রামের মতোই। কমান্ড-লাইনে আপনি (পুনরায়) যে পরিবর্তনশীলটি সংজ্ঞায়িত করেছেন তা প্রোগ্রামের প্রয়োগকে প্রভাবিত করে। এবং কেবলমাত্র (যেহেতু আপনি রফতানি করেন না)। সুতরাং, এই IFSজাতীয় লাইনে পুনরায় সংজ্ঞায়িত ব্যবহার করতে , আপনাকে একাধিক ভেরিয়েবলেরread মান নির্ধারণ করতে বলবে । এই উদাহরণগুলি দেখুন:

 $ data="a  b   c"
 $ echo "$data" | while           read A B C; do echo \|$A\|$B\|\|$C\|; done
 |a|b||c|
 $ echo "$data" | while IFS=      read A B C; do echo \|$A\|$B\|\|$C\|; done
 |a b c||||
 $ echo "$data" | while IFS='a'   read A B C; do echo \|$A\|$B\|\|$C\|; done
 || b c|||
 $ echo "$data" | while IFS='ab'  read A B C; do echo \|$A\|$B\|\|$C\|; done
 || || c|

1 আমি যেমন গিলস থেকে শিখেছি , IFS=''কেবলমাত্র একটি ক্ষেত্র পড়ার সময় সেখানে প্রকৃতপক্ষে স্থাপন করার (ফাঁকা) সুবিধা থাকতে পারে : এটি লাইনের শুরুতে সাদা জায়গার কাটতি এড়ায়।


ভাল .. ধন্যবাদ ... আমি এটি এবার পেয়েছি .. এবং আমি আপনার স্কেচটি ভালবাসি :)
পিটার.ও

ঠিক আছে, এখন আমি আপনার মন্তব্যটি পড়েছি যা দেখুন যে আপনি অন্য প্রশ্নে আমার উত্তরটি লক্ষ্য করেন নি। সম্ভবত আপনি অন্যটিকে রিভার্ট করতে এবং এটি মুছতে পারেন, কারণ এটি সত্যিই একটি সাধারণ সমস্যা?
rozcietrzewiacz

হ্যাঁ, দুটি প্রশ্নের একটি সম্পর্কিত থিম রয়েছে তবে অন্যটির শিরোনামটি হল " IFS= readকেবলমাত্র আইএফএস পরিবেশ পরিবর্তনশীলটিকে পুনরায় সেট করার ক্ষেত্রে কেন অগ্রাধিকার হিসাবে ব্যবহৃত হয়"। আমার সচেতনতা ছিল না, তখন, স্থানীয় ভেরিয়েবলগুলি কমান্ডের কলার দ্বারা সেট করা যায়। এটাই ছিল সেই প্রশ্নের উত্তর। এই প্রশ্নের মূল বক্তব্যটি সম্বোধন করার ক্ষেত্রে এটি আরও বিকশিত হয়েছিল, তবে আমি যখন বুঝতে পেরেছিলাম, আমি ইতিমধ্যে এই প্রশ্নটি জিজ্ঞাসা করেছি ... সম্ভবত দুটি প্রশ্ন দুটি প্রশ্নের মতোই সমান sed, সুতরাং এটিকে রাখার জন্য আমার অনুভূতি ... গুগলদের গুগলে আরও শিরোনাম
পিটার.ও
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.