inserindo um token ao analisar um arquivo - bash

2

Eu tenho um arquivo com essa estrutura:

ma${token}jid-azimi-865131021
javad-ya${token}rip-865132012

e aqui está o meu programa:

IFS="-"

token="12345678"

cat input.txt | while read col1 col2 col3; do
    echo ${col1}
    echo ${col2}
    echo ${col3}
    echo "********************************"
done 

Eu quero inserir ${token} durante a leitura do arquivo. porque o token é uma palavra dinâmica e eu não posso alterá-lo dentro do arquivo toda vez. Então eu adiciono ${token} ao arquivo uma vez. Mas a saída do programa é:

ma${token}jid
azimi
865131021
********************************
javad
ya${token}rip
865132012
********************************

Por que isso está acontecendo? ma${token}jid deve ser expandido assim: echo ma${token}jid , então 12345678 deve ser inserido.

    
por Majid Azimi 21.02.2012 / 12:29

2 respostas

1

O valor de col1 é a string de 13 caracteres ma${token}jid . Quando você escreve echo ${col1} sem aspas, o shell substitui ${col1} pelo valor da variável e executa a divisão de palavras (ou seja, dividindo o valor em palavras separadas em $IFS caracteres) e geração de nome de arquivo (ou seja, globbing). Os valores das variáveis não são expandidos recursivamente usando a sintaxe do shell. Se você usar aspas duplas em torno da substituição de variável (o que você deve fazer, a menos que tenha uma boa razão para não fazer isso), "$col1" se expande diretamente para o valor de col1 .

Se suas strings forem simples o suficiente (ou seja, não contenham caracteres especiais de shell, além do ${token} que você deseja substituir), você poderá construir uma string de $col1 que você avalia como um snippet de shell. No seu exemplo, a linha a seguir imprimiria ma12345678jid :

eval "echo $col1"

Alternativamente, substitua o marcador ${token} pelo valor desejado. Você pode fazer isso com uma substituição de string no bash:

while read -r col1 col2 col3; do
    echo "${col1//'${token}'/$token}"
    echo "${col2}"
    echo "${col3}"
    echo "********************************"
done <input.txt

Você também pode fazer isso com awk , como uma etapa anterior ou posterior ao processamento (dependendo se você deseja executar a substituição em outras colunas também).

<input.txt awk -v repl="$token" '{gsub(/\${token}/, repl); print}' |
while read …

Você pode realizar a substituição com sed , mas somente se tiver certeza de que nenhum dos caracteres &\/ e nova linha aparecem no texto de substituição $token (você pode alterar o caractere separador de / para algo mais se houver outro personagem que você tenha certeza que não aparece em $token ).

<input.txt sed -e "s/\\${token}/$token/" |
while read …
    
por 22.02.2012 / 02:45
3

Variáveis quando ecoadas não estão sujeitas a expansão variável. Prefira eval a echo . Isso pode funcionar para casos simples, mas pode ser interrompido se as strings contiverem | ou aspas. Ou apenas faça a substituição:

echo ${col1/'${token}'/$token}
    
por 21.02.2012 / 12:39

Tags