Sie sollten Variablen in Kleinbuchstaben verwenden (dies ist die beste Vorgehensweise).
Also verwende ich Dateiname und Erweiterung anstelle von FILENAME und EXTENSION
Wenn Sie sagen, dass der Dateiname aus einer Datei gelesen wird, gehe ich davon aus, dass das Skript wie folgt lautet:
read -r filename <file.txt
extension=World.txt
Und dass Sie beide Variablen $ filename und $ extension mit einem Unterstrich verketten wollen _
.
Die von Ihnen angegebenen Beispiele (außer: no double \) funktionieren hier korrekt:
name=${filename}_$extension
name=${filename}'_'$extension
name=$filename\_$extension
Wie einige andere:
name="${filename}"'_'"${extension}"
name="$filename"'_'"$extension"
name="${filename}_${extension}"
Ihr Problem ist also nicht, wie die Variablen zusammenhalten, sondern mit dem Inhalt der Variablen. Es scheint vernünftig zu denken, dass dies:
read -r filename <file.txt
liest einen abschließenden Wagenrücklauf, \r
wenn aus einer Windows-Datei gelesen wird .
Eine einfache Lösung (für ksh, bash, zsh) besteht darin, alle Steuerzeichen aus der gelesenen Variablen zu entfernen:
filename=${filename//[[:cntrl:]]/}
Dies könnte mit einem Wert simuliert werden, der einen Wagenrücklauf hat:
$ 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
Oder ersetzen Sie den Wert von filename
:
$ filename="${filename//[[:cntrl:]]/}"
$ echo "start<$filename>end"
start<Hello>end
Fazit.
Also das:
name="${filename//[[:cntrl:]]/}_${extension//[[:cntrl:]]/}"
Erhält den korrekten Wert name
auch dann, wenn die anderen Variablen Steuerzeichen enthalten.