Bạn nên sử dụng các biến trong chữ thường (đó là cách thực hành tốt nhất).
Vì vậy, tôi sẽ sử dụng tên tệp và phần mở rộng thay vì FILENAME và EXTENSION
Như bạn nói rằng tên tập tin của Wikipedia được đọc từ một tập tin, tôi sẽ cho rằng tập lệnh là:
read -r filename <file.txt
extension=World.txt
Và bạn muốn nối cả hai biến $ filename và $ extension với dấu gạch dưới _
.
Các ví dụ bạn cung cấp (ngoại trừ: không có gấp đôi \) hoạt động chính xác tại đây:
name=${filename}_$extension
name=${filename}'_'$extension
name=$filename\_$extension
Như một số khác:
name="${filename}"'_'"${extension}"
name="$filename"'_'"$extension"
name="${filename}_${extension}"
Vì vậy, vấn đề của bạn không phải là làm thế nào các biến dính vào nhau, mà là với nội dung của các vars. Có vẻ hợp lý khi nghĩ rằng điều này:
read -r filename <file.txt
sẽ đọc trở lại vận chuyển kéo \r
nếu đọc từ một tập tin windows.
Một giải pháp đơn giản (đối với ksh, bash, zsh) là xóa tất cả các ký tự điều khiển khỏi biến đọc:
filename=${filename//[[:cntrl:]]/}
Điều này có thể được mô phỏng với một giá trị có lợi nhuận vận chuyển:
$ 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
Hoặc, thay thế giá trị của filename
:
$ filename="${filename//[[:cntrl:]]/}"
$ echo "start<$filename>end"
start<Hello>end
Phần kết luận.
Vậy đây:
name="${filename//[[:cntrl:]]/}_${extension//[[:cntrl:]]/}"
Sẽ nhận được giá trị chính xác name
ngay cả khi các vars khác chứa các ký tự điều khiển.