ファイルを解析するときにトークンを挿入する - 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}一度ファイルに追加してみました。ただし、プログラムの出力は次のようになります。

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

なぜこれが起こるのですか?ma${token}jid次のように展開して挿入する必要がありますecho ma${token}jid12345678

答え1

エコーされた変数は変数拡張の影響を受けません。eval前に追加します。単純な場合は機能できますが、echo文字列に引用符または引用符が含まれていると|壊れる可能性があります。または、次のものを交換してください。

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

答え2

値はcol113文字の文字列ですma${token}jid。引用符なしで作成すると、echo ${col1}シェルは${col1}変数の値を上書きし、トークン化(つまり、$IFS値を文字から別の単語に分割)とファイル名の生成(つまりワイルドカード)を実行します。変数の値は、シェル構文を使用して再帰的に拡張されません。変数の置換に二重引用符を使用すると(そうしない妥当な理由がない限り使用する必要があります)、"$col1"値は直接拡張されますcol1

文字列が十分に単調な場合(つまり、${token}置き換える文字に加えて特殊な特殊文字が含まれていない場合)、シェルの断片$col1として評価する文字列に基づいて文字列を整理できます。あなたの例では、次の行が印刷されます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 …

関連情報