Bashのawkコマンドでbash変数を使用する方法

Bashのawkコマンドでbash変数を使用する方法

以前に生成された変数セットを使用して、a.ped_snps.tempというファイルの列をフィルタリングし、bash forループでawkを使用したいと思います。

このために、bash変数を作成しました:var_i_1、var_i_2、... var_i_n_blocksは下限として、var_f_1、var_f_2、... var_f_n_blocksは上限として使用されます。

前述のn_blocksは、var_i_1とvar_f_1などで区切られた列を使用して生成されるファイルの数です。次のスクリプトを使用しました。

n_blocks=$(wc -l "a.temp" | awk '{print $1}') # number of blocks to be created, a.temp is the file with the number of blocks

for i in $(seq 1 1 $n_blocks)            # to iterate of first to n_blocks 
    do
    awk -v v_i="$var_i_$i" -v v_f="$var_f_$i" '{     # to declare variables of lower ($var_i_$i) and upper ($var_f_$i) bounds for each iteraction to awk command
    for (i=v_i;i<=v_f;i++) {printf (i==1?"":FS)$i}; print ""     # for statement to print all comlumns between specified in v_i and v_f variables in each iteraction
    }' <a.ped_snps.temp > block_$i.txt       # print one txt file with each block for each iteraction
done

このコードは実行され、for コマンドで指定された正しい反復回数でファイルを提供しますが、各ファイルの最初の列のみが出力に出力されます。

awk(下)とvar_i_1およびvar_f_1 bash変数(以前にそれぞれ保存された値2と4を含む)のみを使用すると、出力(block_1.txt)には必須列$ 2、$ 3、および$ 4などが含まれます。他のブロック。

awk -v v_i="$var_i_1" -v v_f="$var_f_1" '{     # declare variables of lower ($var_i_1) and upper ($var_f_1) bounds for first block (set of cloumns)
    for (i=v_i;i<=v_f;i++) {printf (i==1?"":FS)$i}; print ""     # for statement to print only comlumns between specified in v_i and v_f variables for first block
}' <a.ped_snps.temp > block_1.txt       # print one txt file only with a set of columns specified in v_i and v_f variables

それでは、このコードをbashで実装するのに役立つ人がいますか?とにかく、以前にbashのawkコマンドで生成されたbash変数を使用したいと思います。

私の説明が明確であることを願っています。

よろしくお願いします。

ベストアンサー1

$var_i_$i値などに拡張する$var_i_1と予想しているようですが、$var_i_2残念ながらそうではありません。これを説明するために、次のように設定するとします。

$ var_i_1=23; var_i_2=45; var_i_3=67

それから

$ for i in $(seq 1 3); do awk -v v_i="$var_i_$i" 'BEGIN{print v_i}'; done
1
2
3

ここで起こるのは、シェルが$var_i_$i次のように解決されることです。$var_i_ 関連 $i$var_i_これは設定されていないか、nullになり、v_i単にv_fループインデックス値を継承できるためですi

欲しいものを間接的に達成するいくつかの醜い方法があります。

$ for i in $(seq 1 3); do awk -v v_i="$(eval echo \${var_i_$i})" 'BEGIN{print v_i}'; done
23
45
67

しかし、bashは配列をサポートしているので、よりきれいな解決策は配列をvar_i合計var_f値として使用することです。

$ var_i=(23 45 67)

それから(配列はゼロインデックスであることを覚えておいてください)

$ for i in $(seq 0 2); do awk -v v_i="${var_i[i]}" 'BEGIN{print v_i}'; done
23
45
67

おすすめ記事