ที่จุดเริ่มต้นของสคริปต์เปลือก bash คือบรรทัดต่อไปนี้:
IFS=$'\n'
อะไรคือความหมายที่อยู่เบื้องหลังชุดสัญลักษณ์นี้
IFS=$'\n'
เป็น bashism (+ เชลล์อื่น ๆ ให้ใช้การอ้างอิง ANSI-Cสำหรับการแก้ไขปัญหาดูstackoverflow.com/questions/10748703/ …
ที่จุดเริ่มต้นของสคริปต์เปลือก bash คือบรรทัดต่อไปนี้:
IFS=$'\n'
อะไรคือความหมายที่อยู่เบื้องหลังชุดสัญลักษณ์นี้
IFS=$'\n'
เป็น bashism (+ เชลล์อื่น ๆ ให้ใช้การอ้างอิง ANSI-Cสำหรับการแก้ไขปัญหาดูstackoverflow.com/questions/10748703/ …
คำตอบ:
IFS
ย่อมาจาก "เขตคั่นภายใน" มันถูกใช้โดยเชลล์เพื่อพิจารณาวิธีแยกคำเช่นวิธีการจดจำขอบเขตของคำ
ลองนี้ในเชลล์เช่น bash (เชลล์อื่นอาจจัดการสิ่งนี้แตกต่างกันเช่น zsh):
mystring="foo:bar baz rab"
for word in $mystring; do
echo "Word: $word"
done
ค่าเริ่มต้นสำหรับIFS
ประกอบด้วยอักขระช่องว่าง (ต้องแม่นยำ: space, tab และ newline) ตัวละครแต่ละตัวสามารถเป็นขอบเขตของคำ ดังนั้นด้วยค่าเริ่มต้นของ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 "
(ช่องว่างต่อท้ายและอักขระเว้นวรรคสองตัวระหว่างc
และd
)
IFS=:
มันจะถูกแบ่งออกเป็นสี่เขต: "a"
, "b"
, ""
(สตริงว่าง) และ" c d "
(อีกครั้งสองช่องว่างระหว่างc
และd
) หมายเหตุช่องว่างนำหน้าและต่อท้ายในฟิลด์สุดท้ายIFS=' :'
ก็จะถูกแบ่งออกเป็นห้าเขต: "a"
, "b"
, ""
(สตริงว่าง) และ"c"
"d"
ไม่มีช่องว่างชั้นนำและต่อท้ายที่ใดก็ได้โปรดสังเกตว่าอักขระช่องว่างต่อเนื่องหลายตัวคั่นขอบเขตสองฟิลด์ในตัวอย่างที่สองในขณะที่เครื่องหมายโคลอนหลายคู่ไม่ทำงาน (เนื่องจากไม่ใช่อักขระช่องว่าง)
ในฐานะที่เป็นIFS=$'\n'
ที่เป็นksh93
ไวยากรณ์การสนับสนุนโดยbash
, zsh
, mksh
และ FreeBSD sh
(ด้วยรูปแบบระหว่างเปลือกหอยทั้งหมด) การอ้างถึง bash manpage:
คำของฟอร์ม 'string' ได้รับการปฏิบัติเป็นพิเศษ คำนี้ขยายเป็น "string" โดยใช้อักขระเครื่องหมายทับขวาทับกลับแทนที่ตามที่ระบุโดยมาตรฐาน ANSI C
\n
เป็นลำดับ escape สำหรับการขึ้นบรรทัดใหม่ดังนั้นIFS
สิ้นสุดการตั้งค่าเป็นอักขระขึ้นบรรทัดใหม่เดียว
bash
คู่มือการเขียนสคริปต์หรืออะไรก็ตาม ในหลักข้อมูลที่มีอยู่เช่นการเชื่อมโยงที่ขาดในวิธีที่สำคัญ อย่างไรก็ตามถึงจุดสำคัญสองข้อที่เกี่ยวข้องกับการแยกเปลือก - กลมและ IFS whitespace
unset IFS
เชลล์มีพฤติกรรมแตกต่างกันIFS=
อย่างไร ไบต์แรกใน IFS ก็มีความสำคัญ"${named_array[*]}"
เช่นกัน - แต่ไม่สำคัญว่าเมื่อใดที่การขยายตัวไม่ได้รับการ
$IFS
เป็นหนึ่งในสองสิ่งหลักที่ดำเนินการเมื่อขยายตัวแปรที่ไม่มีเครื่องหมายในบริบทรายการ (เป็นsplit
ส่วนหนึ่งของsplit+glob
โอเปอเรเตอร์) อีกอันหนึ่งกำลังโค้ง เมื่อใช้การแยกงานโดยทั่วไปคุณจะต้องมีปัญหาset -f
ในการปิดการใช้งานชิ้นglob
ส่วน
$IFS
ยังใช้โดยread
คำสั่ง builtin
ภายในเครื่องหมายอัญประกาศเดียวตัวละครบางตัวได้รับการประเมินพิเศษ ตัวอย่างเช่น\n
แปลเป็นบรรทัดใหม่
ดังนั้นบรรทัดนี้จะกำหนดบรรทัดใหม่ให้กับตัวแปร IFS IFS ในที่สุดก็เป็นตัวแปรพิเศษใน bash: Internal Field Separator อย่างที่man bash
บอกไปแล้วว่า
ใช้สำหรับการแยกคำหลังการขยายและเพื่อแยกบรรทัดเป็นคำด้วย
read
คำสั่ง builtin<space><tab><newline>
ค่าเริ่มต้นคือ
dollared single quotes
ซึ่งแตกต่างจากคำพูดเดี่ยวง่าย ๆ
สำหรับระยะสั้นIFS=$'\n'
กำหนดขึ้นบรรทัดใหม่ให้กับตัวแปร\n
IFS
$'string'
สร้างเป็นกลไกการอ้างอิงที่ใช้ในการถอดรหัส ANSI C เช่นลำดับหนี ไวยากรณ์นี้มาจากksh93
และเป็นแบบพกพาที่ทันสมัยเช่นเปลือกbash
, zsh
, ,pdksh
busybox sh
รูปแบบนี้ไม่ได้ถูกกำหนดโดย POSIX แต่ได้รับการยอมรับสำหรับปัญหา SUS 7
ฉันชอบที่จะอธิบาย$IFS
ผ่านตัวอย่าง:
สมมติว่าคุณต้องการ cp หรือ mv หรือไฟล์อื่นที่กำลังดำเนินการ IFS ว่างเปล่าโดยค่าเริ่มต้นเมื่อไฟล์ของคุณมี meta ถ่านหรือพื้นที่เช่น:
Linux Administration.pdf
หรือFree Software Fundation.ogg
แน่นอนคุณจะมี probelm เพราะ: Linux พิจารณา แยกพารามิเตอร์และ Administartion พิจารณาพารามิเตอร์แยกดังนั้นทุบตีมี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