解析文件时插入令牌 - bash

解析文件时插入令牌 - bash

我有一个具有以下结构的文件:

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

这是我的程序:

IFS="-"

token="12345678"

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

我想${token}在读取文件时插入。因为 token 是一个动态单词,我不能每次都在文件中更改它。所以我添加${token}到文件一次。但程序的输出是:

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

为什么会发生这种情况?ma${token}jid应该像这样展开:echo ma${token}jid,然后12345678应该插入。

答案1

回显时的变量不受变量扩展的影响。前置evalecho.这可能适用于简单的情况,但如果您的字符串包含|或引号,则可能会中断。或者,只需进行替换:

echo ${col1/'${token}'/$token}

答案2

的值为col113 个字符的字符串ma${token}jid。当您echo ${col1}不加引号写入时,shell 会替换${col1}为变量的值,然后执行分词(即在$IFS字符处将值分解为单独的单词)和文件名生成(即通配符)。变量值不会使用 shell 语法进行递归扩展。如果您在变量替换周围使用双引号(除非您有充分的理由不这样做,否则您应该这样做),则"$col1"直接扩展为 的值col1

如果您的字符串足够温和(即,除了${token}您想要替换的字符之外,不包含 shell 特殊字符),那么您可以根据$col1您作为 shell 片段评估的字符串构造一个字符串。在您的示例中,将打印以下行ma12345678jid

eval "echo $col1"

或者,将标记替换${token}为所需值。您可以通过 bash 中的字符串替换来完成此操作:

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

您还可以使用awk, 作为预处理或后处理步骤(取决于您是否也想在其他列中执行替换)。

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

您可以使用 执行替换,但前提是您确定替换文本中sed没有出现任何字符和换行符(如果您确定没有出现另一个字符,则可以将分隔符更改为其他字符)在)。&\/$token/$token

<input.txt sed -e "s/\\\${token}/$token/" |
while read …

相关内容