'IFS' คืออะไร


คำตอบ:


17

IFSย่อมาจาก- มันเป็นตัวละครที่แยกฟิลด์ ในตัวอย่างที่คุณโพสต์จะถูกตั้งเป็นอักขระบรรทัดใหม่ ( ); ดังนั้นหลังจากที่คุณตั้งค่ามันจะประมวลผลบรรทัดข้อความต่อบรรทัด ในตัวอย่างนั้นคุณสามารถเปลี่ยนค่าของ(เป็นตัวอักษรบางตัวที่คุณมีในไฟล์อินพุต) และตรวจสอบว่าจะแยกข้อความอย่างไรInput Internal Field Separator\nforIFS

BTW จากคำตอบที่คุณโพสต์โซลูชันที่สองคือแนะนำ ...

ในฐานะที่เป็น@jasonwryanสังเกตเห็นก็ไม่ได้แต่Input Internalชื่อInputมาจากawkที่มีอยู่ยัง-OFSOutput Field Separator


1
โปรดทราบว่า IFS ยังใช้สำหรับการรวมพารามิเตอร์สำหรับเอาต์พุต จากหน้า bash man: "เมื่อการขยายเกิดขึ้นภายในเครื่องหมายคำพูดคู่มันจะขยายเป็นคำเดียวที่มีค่าของแต่ละพารามิเตอร์คั่นด้วยอักขระตัวแรกของตัวแปรพิเศษของ IFS"
Eric

หนึ่งควรทราบว่าในขณะที่Sมีไว้สำหรับคั่นในเปลือกเป้าหมายที่มันมาจาก ในเปลือกกรและอื่น ๆ ส่วนใหญ่บอร์นเหมือนเปลือกเป็นที่ได้รับในขณะนี้ที่ระบุไว้ตามPOSIXที่Sเป็นตัวคั่น (เพียงยืดจินตนาการของคุณบิต) เป็นA::B:เช่นนี้แบ่งออกเป็น "A", "" และ "B" (ไม่มีการพิเศษ "") ที่แตกต่างจากawk's FSหรือธงขยายตัวพารามิเตอร์ของs zsh
Stéphane Chazelas

27

IFSไม่เกี่ยวข้องโดยตรงกับการวนซ้ำมันเกี่ยวข้องกับการแยกคำ IFSกำหนดทางอ้อมว่าเอาต์พุตจากคำสั่งแบ่งออกเป็นชิ้นส่วนที่วนซ้ำ

เมื่อคุณมีการทดแทนตัวแปรที่ไม่มีการป้องกัน$fooหรือการทดแทนคำสั่ง$(foo)มีสองกรณี:

  • หากบริบทคาดว่าจะมีคำเดียวเช่นเมื่อการแทนที่อยู่ระหว่างเครื่องหมายคำพูดคู่"$foo"หรือในการกำหนดตัวแปรx=$fooดังนั้นสตริงที่เป็นผลมาจากการแทนที่จะถูกใช้ตามที่เป็นอยู่
  • หากบริบทคาดว่าจะมีหลายคำซึ่งเป็นกรณีส่วนใหญ่การขยายเพิ่มเติมอีกสองครั้งจะถูกดำเนินการบนสตริงผลลัพธ์:
    • สตริงจะถูกแบ่งออกเป็นคำพูด อักขระใด ๆ ที่ปรากฏขึ้น$IFSจะถือเป็นตัวแยกคำ ตัวอย่างเช่นIFS=":"; foo="12:34::78"; echo $fooพิมพ์12 34 ​ 78(ที่มีสองช่องว่างระหว่าง34และ78เนื่องจากมีคำว่าง)
    • แต่ละคำจะถือว่าเป็นรูปแบบ glob และขยายเข้าไปในรายชื่อไฟล์ ตัวอย่างเช่นfoo="*"; echo $fooพิมพ์รายการของไฟล์ในไดเรกทอรีปัจจุบัน

สำหรับลูปเช่นเดียวกับบริบทอื่น ๆ คาดหวังรายการคำ ดังนั้น

for x in $(foo); do 

แบ่ง$(foo)ออกเป็นคำและถือว่าแต่ละคำเป็นรูปแบบกลม ค่าเริ่มต้นของIFSเป็นพื้นที่แท็บและการขึ้นบรรทัดใหม่ดังนั้นถ้าfooพิมพ์ออกมาสองเส้นhello worldและhowdyแล้วร่างกายห่วงจะถูกดำเนินการด้วยx=helloแล้วและx=world x=howdyหากIFSมีการเปลี่ยนแปลงอย่างชัดเจนที่จะมีการขึ้นบรรทัดใหม่เท่านั้นแล้ววงที่จะดำเนินการสำหรับการและhello world howdyหากIFSมีการเปลี่ยนแปลงจะเป็นoแล้ววงที่จะดำเนินการสำหรับhell, ​ w, rld​␤h(ที่​␤เป็นตัวอักษรขึ้นบรรทัดใหม่) wdyและ


ทำไมคุณพูดถึง "ทางอ้อม" ใน"IFS indirectly determines how ..."?
αғsнιη


5

จาก man bash

IFS The Internal Field Separator ที่ใช้สำหรับการแบ่งคำหลังจากการขยายและเพื่อแยกบรรทัดเป็นคำด้วยคำสั่ง read builtin ค่าเริ่มต้นคือ "<space> <tab> <newline>"

นี่เป็นหนึ่งในตัวแปรภายในของ Bash มันเป็นตัวกำหนดว่า Bash รู้จักฟิลด์หรือขอบเขตของคำอย่างไรเมื่อตีความสตริงอักขระ

ในขณะที่มันเริ่มต้นที่ช่องว่าง (พื้นที่แท็บและขึ้นบรรทัดใหม่) มันอาจมีการเปลี่ยนแปลงตัวอย่างเช่นในการแยกไฟล์ข้อมูลที่คั่นด้วยเครื่องหมายจุลภาค

http://tldp.org/LDP/abs/html/internalvariables.html


0

นอกจากนี้คำตอบที่ดีก่อนหน้านี้ให้ฉันเพียงแค่เพิ่มที่ไอเอฟเอเป็นประโยชน์อย่างมากสำหรับการแยกที่มีประสิทธิภาพและแบบพกพาในกรณีที่เรียบง่ายในการรวมกันกับชุด มีประสิทธิภาพเพราะหลีกเลี่ยงการใช้ subshells และเครื่องมือวางไข่เช่น grep หรือ sed:

resolutions="640x480,320x240"
xIFS=$IFS
IFS=','
for res in $resolutions; do
    xxIFS=$IFS
    IFS='x'
    set -- $res
    width=$1
    height=$2
    # handle width and height
    IFS=$xxIFS
done;
IFS=$xIFS

เพียงแค่ทราบว่าเราต้องจัดเก็บและกู้คืนค่าก่อนหน้าของIFSเพื่อหลีกเลี่ยงการแตกที่ไม่พึงประสงค์ในส่วนอื่น ๆ ของสคริปต์

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.