Você pode usar algo assim:
NAME=$(echo ${FILENAME}_${EXTENSION})
Isso também funciona:
NAME=${FILENAME}_${EXTENSION}
Eu preciso concatenar duas variáveis para criar um nome de arquivo que tenha um sublinhado.
Vamos chamar minhas variáveis $FILENAME
e $EXTENSION
onde filename é lido de um arquivo.
FILENAME=Hello
EXTENSION=WORLD.txt
Agora ...
Eu tentei o seguinte sem sucesso:
NAME=${FILENAME}_$EXTENSION
NAME=${FILENAME}'_'$EXTENSION
NAME=$FILENAME\_$EXTENSION
Eu sempre recebo algum tipo de saída estranha. Geralmente o sublinhado primeiro.
Eu preciso que seja
echo $NAME
Hello_WORLD.txt
Seu:
NAME=${FILENAME}_$EXTENSION
NAME=${FILENAME}'_'$EXTENSION
estão todos bem, então seria:
NAME=${FILENAME}_${EXTENSION}
NAME=$FILENAME'_'$EXTENSION
NAME=$FILENAME\_$EXTENSION
NAME=$FILENAME"_$EXTENSION"
(mas certamente não como ele usa NAME=$(echo ${FILENAME}_${EXTENSION})
echo
e o operador split+glob
).
NAME=$FILENAME_$EXTENSION
teria sido o mesmo que:
NAME=${FILENAME_}${EXTENSION}
como _
(ao contrário de \
ou '
) é um caractere válido em um nome de variável.
Seu problema é que você tinha linhas delimitadas com CRLF em vez de apenas LF, o que significava que o conteúdo dessas variáveis terminava em caractere CR.
O caractere CR, quando escrito em um terminal, diz ao terminal para mover o cursor para o início da linha. Então Hello<CR>_WORLD.TXT<CR>
quando enviado para um terminal seria mostrado como _WORLD.TXT
(sobrescrevendo o Hello
).
Você deve usar variáveis em minúsculas (é a melhor prática).
Então, eu vou usar o nome do arquivo e extensão em vez de FILENAME e EXTENSION
Como você diz que "nome do arquivo é lido de um arquivo", presumo que o script seja:
read -r filename <file.txt
extension=World.txt
E que você deseja concatenar as variáveis $ filename e $ extension com um sublinhado _
.
Os exemplos que você fornece (exceto: no double \) funcionam corretamente aqui:
name=${filename}_$extension
name=${filename}'_'$extension
name=$filename\_$extension
Como alguns outros:
name="${filename}"'_'"${extension}"
name="$filename"'_'"$extension"
name="${filename}_${extension}"
Então, o seu problema não está em como as variáveis estão juntas, mas com o conteúdo das vars. Parece razoável pensar que isso:
read -r filename <file.txt
lerá um retorno de carro à direita \r
se estiver lendo de um arquivo do Windows.
Uma solução simples (para ksh, bash, zsh) é remover todos os caracteres de controle da variável de leitura:
filename=${filename//[[:cntrl:]]/}
Isso pode ser simulado com um valor que tenha um retorno de carro:
$ 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
Ou, substituindo o valor de filename
:
$ filename="${filename//[[:cntrl:]]/}"
$ echo "start<$filename>end"
start<Hello>end
Então isso:
name="${filename//[[:cntrl:]]/}_${extension//[[:cntrl:]]/}"
Obtém o valor correto para name
, mesmo se as outras variantes contiverem caracteres de controle.
Eu mudei para usar a sintaxe ${FILENAME}_${EXTENSION}
mencionada acima.
Eu costumava usar $()
quando eu precisava concatenar duas variáveis com um sublinhado. Por exemplo, $YYYYMMDD$()_$HHMMSS
para gerar um nome de arquivo contendo um registro de data e hora no formato AAAAMMDD_HHMMSS. O meio $()
não retorna nada e divide as duas variáveis.
Eu usei time
para medir as atribuições usando o método $YYYYMMDD$()_$HHMMSS
e algumas delas acima, e todas elas relataram 0ms no servidor antigo no qual estou usando. O desempenho não parece ser um problema.
resposta de Stéphane Chazelas ,
NAME=${FILENAME}_$EXTENSION
é, evidentemente, a melhor resposta e deve ser a resposta aceita. Mas, no espírito da resposta do user208145 , aqui está uma alternativa:
UNDERSCORE='_'
NAME=$FILENAME$UNDERSCORE$EXTENSION
Você também pode usar isto: separe os vars separados com espaços e concatene-os usando tr para remover o espaço.
TableNameToCreate="MyTable"
# concatenation work is done here
$(echo "$TableNameToCreate _my_other_Info " | tr -d " ")
#Proof
echo "Var to create with var pasted as prefix to suffix
$(echo "$TableNameToCreate _my_other_Info " | tr -d " ")
. "
# create a new var
NewVar=$(echo "$TableNameToCreate _my_other_Info " | tr -d " ")
#proof
echo "$NewVar"
Tags bash shell-script