ฉันสังเกตเห็นว่าการกำหนด newline IFSควรมี $ เป็นคำนำหน้า
IFS=$'\n'
แต่ถ้าตั้งลำไส้ใหญ่เพียง
IFS=:
คือ\nเป็นตัวแปรหรือไม่?
ฉันสังเกตเห็นว่าการกำหนด newline IFSควรมี $ เป็นคำนำหน้า
IFS=$'\n'
แต่ถ้าตั้งลำไส้ใหญ่เพียง
IFS=:
คือ\nเป็นตัวแปรหรือไม่?
คำตอบ:
ว่า$'...'ในbashไม่พารามิเตอร์การขยายตัวก็เป็นชนิดพิเศษนำโดยอ้างksh93ว่าการขยายตัวของผู้ที่\n, \x0a, \12รหัสตัวอักษรขึ้นบรรทัดใหม่ นอกจากนี้ยังเพิ่มzsh และยังมีในขณะที่มี นอกจากนี้ยังสนับสนุนรูปแบบเช่น\u000aksh93bash\cjzsh\C-Jksh93\x{a}
$เป็นคิวที่มันเป็นรูปแบบบางส่วนหรือการขยายตัว แต่ในกรณีใด ๆ มันแตกต่างจากรูปแบบอื่น ๆ ของการขยายการใช้งาน$(เช่น$((1 + 1)), $paramหรือ$(cmd)) ในการที่จะไม่ได้ดำเนินการให้อยู่ในเครื่องหมายหรือนี่เอกสาร ( echo "$'x'"เอาท์พุท$'x'ในเปลือกหอยทั้งหมดก็คือไม่ได้ระบุต่อ POSIX) และการขยายตัวของมันไม่ได้อยู่ภายใต้การแยก + glob แน่นอนว่ามันใกล้กับโอเปอร์เรเตอร์ของ quoting มากกว่าโอเปอเรเตอร์การขยาย
IFS=\nจะตั้งไอเอฟเอไปn( \จะถือว่าเป็นผู้ประกอบการอ้าง) และIFS="\n"หรือจะตั้งไอเอฟเอไปที่ตัวละครสองตัวทับขวาและIFS='\n'n
คุณยังสามารถใช้:
IFS='
'
หรือ
IFS="
"
หรือ
IFS=$'
'
ผ่านการขึ้นบรรทัดใหม่ที่แท้จริง แต่ที่ชัดเจนน้อยกว่า (และเป็นหนึ่งในไม่สามารถดูอื่น ๆ กว่าการใช้สิ่งที่ต้องการset listในviไม่ว่าจะ$IFSมีตัวละครอื่น ๆ ในระยะห่างรหัสที่)
IFS=:, IFS=':', IFS=":", IFS=$':'ทุกชุด IFS ไป:จึงไม่ได้เรื่องที่คุณใช้
$'...'ได้รับการสนับสนุน (ด้วยรูปแบบ) อย่างน้อย: ksh93, zsh, bash, mksh, busybox sh, shFreeBSD ksh93และbashยังมี$"..."รูปแบบของคำพูดที่ใช้สำหรับการแปลข้อความแม้ว่ามันจะไม่ค่อยได้ใช้เพราะมันยุ่งยากในการปรับใช้และใช้งานได้แบบพกพาและเชื่อถือได้
esและfishหอยยังสามารถใช้\nนอกของคำพูดที่จะขยายไปขึ้นบรรทัดใหม่
เครื่องมือบางอย่างเช่นprintfการใช้งานบางอย่างของechoหรือawkยังสามารถขยายได้\nด้วยตนเอง ตัวอย่างเช่นหนึ่งสามารถทำได้:
printf '\n'
awk 'BEGIN{printf "\n"}'
echo
echo '\n\c' # UNIX compliant echos only
ไปที่เอาต์พุตของอักขระบรรทัดใหม่ แต่โปรดทราบว่า:
IFS = $ (printf '\ n')
จะไม่ทำงานเนื่องจากการทดแทนคำสั่ง ( $(...)) ตัดอักขระบรรทัดใหม่ที่ต่อท้ายทั้งหมด อย่างไรก็ตามคุณสามารถใช้:
eval "$(printf 'IFS="\n"')"
ซึ่งใช้งานได้เนื่องจากผลลัพธ์ของการprintfสิ้นสุดใน"อักขระไม่ใช่บรรทัดใหม่
ตอนนี้เพื่อความสมบูรณ์ในrcเชลล์และอนุพันธ์ (เช่นesหรือakanga) $'\n'นั้นเป็นการขยายตัวของ\nตัวแปรนั้น(ตัวแปรที่มีชื่อคือลำดับของอักขระสองตัว\และn) เปลือกหอยเหล่านั้นไม่ได้มีข้อ จำกัด '...'ในสิ่งที่ตัวละครชื่อตัวแปรอาจจะมีและมีเพียงหนึ่งในประเภทของคำพูด:
$ rc
; '\n' = (foo bar)
; echo $'\n'
foo bar
; echo $'\n'(1)
foo
rcตัวแปรยังถูกส่งออกไปยังสภาพแวดล้อมทั้งหมด แต่อย่างน้อยในตัวแปร Unix rcสำหรับชื่อตัวแปรเช่น\nเวอร์ชันตัวแปรสภาพแวดล้อมผ่านการเข้ารหัส:
; env | grep foo | sed -n l
__5cn=foo\001bar$
( 0x5cเป็นค่าไบต์ของ ASCII \ดูด้วยว่าตัวแปรอาร์เรย์นั้นถูกเข้ารหัสด้วย 0x1 ไบต์เป็นตัวคั่น)
นี่คือการอ้างอิง ANSI-C :
คำของแบบฟอร์ม
$'string'ได้รับการปฏิบัติเป็นพิเศษ คำขยายออกไปstringโดยมีอักขระเครื่องหมายทับขวาทับกลับแทนที่ตามที่ระบุโดยมาตรฐาน ANSI C
ดังนั้น$'\n'จะถูกแทนที่ด้วยขึ้นบรรทัดใหม่
นี่คือที่ไม่เกี่ยวข้องกับเปลือกขยายตัวพารามิเตอร์$แม้จะมีการใช้งานของ
สตริงดังกล่าว$'\n'ได้รับการแนะนำโดยksh93และไม่ได้เป็นส่วนหนึ่งของมาตรฐาน POSIX
พวกเขาอนุญาตให้มีการใช้มากที่สุด C หนีเหมือนกันเช่นและหนีออกที่ได้รับการสนับสนุนโดย$'\u2345'echo
โปรดทราบว่าหากคุณไม่ชอบ (ในกรณีของ ksh93 หรือ bash) เพื่อใช้วิธีการหลบหนีคุณยังอาจใช้:
IFS='
'
ซึ่งเทียบเท่า แต่อ่านยากกว่า
BTW: ส่วนขยายนี้ผ่านการรับรองมาตรฐาน POSIX แล้ว แต่มีกำหนดสำหรับSUSv8ที่คาดว่าจะไม่ปรากฏก่อนปี 2020 เนื่องจากเราจำเป็นต้องทำงานในความล่าช้าของเราที่อยู่เบื้องหลังรายการข้อผิดพลาดในปัจจุบัน
$'...' พวกเขากำลังมากขึ้นเช่นคนสำหรับอาร์กิวเมนต์รูปแบบของecho printfสำหรับecho, 0 ต้องการใน\0123ขณะที่สำหรับ$'...'และprintfฟอร์แมต, \0123จะขึ้น\012บรรทัดใหม่ตามด้วยครอก 3
$'...'ข้อมูลจำเพาะยังคงถูกกล่าวถึง ยังมีอีกหลายประเด็นที่จะต้องแก้ไขด้วยถ้อยคำที่เสนอในปัจจุบัน
\uxxxxการขยายตัว) และไม่มีการแก้ไขที่จะรองรับการใช้งานที่มีอยู่ ดังนั้นจึงอาจไม่ทำให้เป็น POSIX เวอร์ชันถัดไป บางทีพวกเขาอาจจะออกจาก\uxxxxการขยายตัวออกไปสำหรับ issue8 $'\n'ดังนั้นเราจึงยังคงสามารถมีอย่างน้อย
+1สำหรับระดับความรู้ปกติของมนุษย์