බාෂ් ස්ක්‍රිප්ටින් හි IFS = $ '\ n' යන්නෙහි තේරුම කුමක්ද?


183

බෑෂ් ෂෙල් ස්ක්‍රිප්ටයක ආරම්භයේ දී පහත පේළිය වේ:

IFS=$'\n'

මෙම සංකේත එකතුව පිටුපස ඇති තේරුම කුමක්ද?


3
Unix.stackexchange.com/questions/26784/understanding-ifs සහ එය උපුටා දක්වන ප්‍රශ්නද බලන්න .
ගිලෙස්ගේ SO- නපුරු වීම නවත්වන්න '

vim syntax මෙය මට දෝෂයක් ලෙස ඉස්මතු කරයි; නිවැරදි කරන්න?
theonlygusti

IFS=$'\n'(+ වෙනත් ෂෙල් වෙඩි, ANSI-C උපුටා දැක්වීම භාවිතා කරන්න , වැඩකරන ස්ථාන
pevik

Answers:


218

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=:ලූපය ක්‍රියාත්මක කිරීමට පෙර සැකසීමට උත්සාහ කරන්න . මෙවර ප්‍රති result ලය වන්නේ:

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 "(අතර අවකාශය හා අවකාශය චරිත දෙකක් නොදැවී ක්රීඩා cසහ d).

  1. සමග IFS=:: එය ක්ෂේත්ර හතරකට භේදය වනු ඇත "a", "b", ""(හිස් අගයක්) සහ " c d "(නැවත, මේතරම් දෙකක් cහා d). අවසාන ක්ෂේත්‍රයේ ප්‍රමුඛ හා පසුපස සුදු අවකාශය සටහන් කරන්න.
  2. සමග IFS=' :', එය පහ ක්ෂේත්ර වෙන් වනු ඇත: "a", "b", ""(හිස් අගයක්), "c"හා "d". කොතැනකවත් ප්‍රමුඛ හා පසුපස සුදු අවකාශයක් නොමැත.

දෙවන උදාහරණයේ බහු, අඛණ්ඩ සුදු අවකාශයේ අක්ෂර ක්ෂේත්‍ර දෙකක් වෙන් කරන ආකාරය සැලකිල්ලට ගන්න.

සඳහා පරිදි IFS=$'\n', බව ය ksh93ද සහයෝගය කාරක රීති bash, zsh, mkshඒ අතරින් කිහිපයකි sh(සියළුම ෂෙල් වෙඩි අතර වෙනස්කම් සහිතව). Bash manpage උපුටා දැක්වීම:

String 'නූල්' ආකෘතියේ වචන විශේෂයෙන් සලකනු ලැබේ. ANSI C ප්‍රමිතියෙන් නියම කර ඇති පරිදි බැක්ස්ලෑෂ්-ගැලවී ගිය අක්ෂර ප්‍රතිස්ථාපනය කර වචනය "නූල්" දක්වා විහිදේ.

\nයනු නව රේඛාවක් සඳහා පැනීමේ අනුක්‍රමයයි, එබැවින් IFSඅවසන් වන්නේ තනි නව රේඛා අක්ෂරයකටය.


3
මෙය හොඳයි, නමුත්, මගේ මතය අනුව, ඔබ bashස්ක්‍රිප්ටින් මාර්ගෝපදේශයට වඩා පොසික්ස් පිරිවිතර කියවීමට හා තේරුම් ගැනීමට වඩා හොඳ දෙයක් කරයි. ප්රධාන වශයෙන්, එවැනි සබැඳිවල ඇති තොරතුරු වැදගත් ආකාරවලින් අඩු ය. කෙසේ වෙතත්, ෂෙල් බෙදීම් සම්බන්ධයෙන් තීරණාත්මක කරුණු දෙකක් මග හැරේ - ග්ලෝබින් සහ අයිඑෆ්එස් වයිට්ස්පේස්.
mikeserv

ikmikeserv ස්තූතියි, මම IFS සුදු අවකාශය පිළිබඳ තොරතුරු කිහිපයක් එකතු කළෙමි. ඒ ගැන දැනගෙන හිටියේ නැහැ. :)
Tblue

4
අදාළ නොවේ, නමුත් ඔබ කුතුහලයෙන් සිටී නම්, unset IFSකවචයක් ඊට වඩා වෙනස් ආකාරයකින් හැසිරෙන්නේ කෙසේදැයි බැලීමට ඔබට අවශ්‍ය විය හැකිය IFS=. අයිඑෆ්එස් හි පළමු බයිටය ද විශේෂිත "${named_array[*]}"වේ - නමුත් ප්‍රසාරණය
නොකල

තවත් කරුණු කිහිපයක්: 1- වචන බෙදීම, පාලනය කරනු $IFSලබන්නේ ලැයිස්තුගත සන්දර්භය තුළ නම් නොකළ විචල්‍යයක් පුළුල් කිරීමෙන් පසුව සිදු කෙරෙන ප්‍රධාන කරුණු දෙකෙන් එකකි (එය ක්‍රියාකරුගේ splitකොටසයි split+glob). අනෙක ග්ලෝබල් කිරීමයි. වැඩ බෙදීම් භාවිතා කරන විට set -f, globකොටස අක්‍රීය කිරීම සඳහා ඔබ සාමාන්‍යයෙන් නිකුත් කළ යුතුය .
ස්ටෙෆාන් චසෙලාස්

4
3- $IFSreadබිල්ඩින් විධානය මඟින් භාවිතා කරයි
ස්ටෙෆාන් චසෙලාස්

23

ඩොලරඩ් තනි උපුටා දැක්වීම් ඇතුළත, සමහර අක්ෂර විශේෂයෙන් ඇගයීමට ලක් කෙරේ. උදාහරණයක් ලෙස, \nනව පේළියකට පරිවර්තනය කර ඇත.

ඉතින්, මෙම විශේෂිත රේඛාව විචල්ය IFS වෙත නව රේඛාවක් පවරයි. අයිඑෆ්එස්, බැෂ් හි විශේෂ විචල්‍යයකි: අභ්‍යන්තර ක්ෂේත්‍ර බෙදුම්කරු. කියන පරිදි man bash, එය

ප්‍රසාරණයෙන් පසු වචන බෙදීම සඳහා සහ readබිල්ඩින් විධානය සමඟ රේඛා වචන වලට බෙදීමට භාවිතා කරයි. පෙරනිමි අගය වේ <space><tab><newline>.


7
dollared single quotesසරල තනි උපුටා දැක්වීම් වලට වඩා වෙනස් වන +1 සඳහන් කිරීම සඳහා +1 .
ස්නෝක්‍රෑෂ්

2
Single ස්නෝක්‍රෑෂ් +1 සරල තනි උපුටා දැක්වීම්වලට වඩා වෙනස් ඩොලරඩ් තනි උපුටා දැක්වීම් සඳහා +1 කීම සඳහා . කණගාටුයි, එයට උදව් කළ නොහැක :) නමුත් ඇත්ත වශයෙන්ම එය පෙන්වා දීම ඇත්තෙන්ම හොඳ දෙයක් නිසා එය වැදගත් ය!
Pryftan

1
1 +1 සඳහා +1 සඳහා ප්‍රයිෆ්ටන් +1 ... ඔබ දන්නවා ... එය ඇත්තෙන්ම වැදගත්.
0xc0de

X 0xc0de නිසැකවම එකඟයි! එයට ස්තුතියි! :)
ප්‍රිෆ්ටන්

15

කෙටියෙන් කිවහොත්, විචල්‍යයට IFS=$'\n'නව රේඛාවක් යොදන්න .\nIFS

$'string'ඉදිකිරීම් යනු පැනීමේ අනුපිළිවෙල වැනි ANSI C විකේතනය කිරීමට භාවිතා කරන උපුටා දැක්වීමේ යාන්ත්‍රණයකි. මෙම කාරක රීති පැමිණෙන්නේ ksh93, සහ වැනි නූතන ෂෙල් කිරීමට අතේ ගෙන යා හැකි විය bash, zsh, pdksh, busybox sh.

මෙම වාක්‍ය ඛණ්ඩය POSIX විසින් නිර්වචනය කර නැත, නමුත් SUS නිකුතුව 7 සඳහා පිළිගනු ලැබීය .


-1

මම $IFSඋදාහරණයකින් පැහැදිලි කිරීමට
කැමැත්තක් දැක්වුවෙමි : ඔබට සීපී හෝ එම්වී හෝ වෙනත් ගොනුවක් ක්‍රියාත්මක වීමට අවශ්‍ය නම්, අයිඑෆ්එස් හි අක්‍රීයව හිස් වේ, ඔබේ ලිපිගොනු වල මෙටා චාර් හෝ අවකාශය ඇති විට:
Linux Administration.pdfහෝ Free Software Fundation.ogg, ඔබට ප්‍රොබෙල්ම් ඇති බව සහතිකයි, මන්ද: ලිනක්ස් සලකා බලන්න වෙන් වෙන් පරාමිතිය සහ පරිපාලන අංශය වෙනම පරාමිතියක් සලකා බලයි. එබැවින් බාෂ් සතුව ඇත 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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.