คุณควรใช้ตัวแปรเป็นตัวพิมพ์เล็ก (เป็นแนวปฏิบัติที่ดีที่สุด)
ดังนั้นฉันจะใช้ชื่อไฟล์และส่วนขยายแทน FILENAME และ EXTENSION
ดังที่คุณพูดว่า“ ชื่อไฟล์อ่านจากไฟล์” ฉันจะสมมติว่าสคริปต์คือ:
read -r filename <file.txt
extension=World.txt
และที่คุณต้องการที่จะเชื่อมตัวแปรทั้งสอง $ ชื่อไฟล์และ $ _
ส่วนขยายที่มีการขีดเส้นใต้
ตัวอย่างที่คุณให้ (ยกเว้น: ไม่มี double \) ทำงานอย่างถูกต้องที่นี่:
name=${filename}_$extension
name=${filename}'_'$extension
name=$filename\_$extension
ในขณะที่อื่น ๆ :
name="${filename}"'_'"${extension}"
name="$filename"'_'"$extension"
name="${filename}_${extension}"
ดังนั้นปัญหาของคุณไม่ได้อยู่ที่ว่าตัวแปรเชื่อมโยงกันอย่างไร แต่มีเนื้อหาของ vars ด้วย ดูเหมือนว่าสมเหตุสมผลที่จะคิดว่าสิ่งนี้:
read -r filename <file.txt
จะอ่าน carriage trailing return \r
ถ้าอ่านจากไฟล์ windows
วิธีแก้ปัญหาง่ายๆ (สำหรับ ksh, bash, zsh) คือการลบอักขระควบคุมทั้งหมดออกจากตัวแปรอ่าน:
filename=${filename//[[:cntrl:]]/}
สิ่งนี้อาจจำลองด้วยค่าที่มีการคืนค่าขนส่ง:
$ filename=$'Hello\r'
$ echo "starting<$filename>end"
>endting<Hello ### note the return to the start of line.
$ echo "starting<${filename//[[:cntrl:]]/}>end"
starting<Hello>end
หรือแทนที่ค่าของfilename
:
$ filename="${filename//[[:cntrl:]]/}"
$ echo "start<$filename>end"
start<Hello>end
ข้อสรุป
ดังนั้นนี่คือ:
name="${filename//[[:cntrl:]]/}_${extension//[[:cntrl:]]/}"
จะได้รับค่าที่ถูกต้องname
แม้ว่า vars อื่นจะมีอักขระควบคุม