AWK: ヘッダーのない行のネストされた条件付きサブセット

AWK: ヘッダーのない行のネストされた条件付きサブセット

かなり具体的な質問があり、awkを使用した条件付きサブセット化に関する多くの情報を見つけることができましたが、私の状況に一般化できるほど明確なコードがありませんでした。ファイル「keys」とファイル「features」の両方があります。ヘッダーなし. 「キー」テーブルには、KEY と GROUP (それぞれ 1 列目と 2 列目) の 2 つの変数が含まれています (以下に例を示します)。

    1          GROUP0
    2          GROUP0
    3          GROUP1
    4          GROUP1
    5          GROUP2
    6          GROUP2  

ファイル「features」には、次のようなウィジェットの機能のリストが含まれています (それぞれ ID、FEATURE、VALUE の 1 列目、2 列目、3 列目)。

    A           num_user     10
    A           KEY          4
    B           num_user     2
    B           KEY          2
    B           battery      Large
    C           num_user     10
    C           KEY          15
    D           num_user     2
    D           KEY          2
    D           battery      Small
    E           num_user     2
    E           KEY          7
    E           battery      Small

ハードコードされた「GROUP」値のリストの「keys」の「KEY」列にある「KEY」値を持つIDのすべての行を選択しようとしています。望ましい結果は次のとおりです。

    A           num_user     10
    A           KEY          4
    B           num_user     2
    B           KEY          2
    B           battery      Large
    D           num_user     2
    D           KEY          2
    D           battery      Small

何か案は?

答え1

以下は awk を使用した 3 パスのアプローチです。

FNR == 1 {
        fn++        # counter for File Number, starts at 1
}

fn == 1 {
        key[$1] = 1 # first file: store keys
}

fn == 2 && $2 == "KEY" && $3 in key {
        id[$1] = 1  # second file, first pass: store id's
}

fn == 3 && $1 in id # second file, 2nd pass: print rows

上記が に保存されていると仮定するとselectrows.awk、次のように使用します。

awk -f selectrows.awk keys.txt features.txt features.txt

または、すべてを 1 行に記述します。

awk 'FNR == 1 {f++}; f == 1 {k[$1]}; f == 2 && $2=="KEY" && $3 in k {i[$1]}; f == 3 && $1 in i' keys.txt features.txt features.txt

答え2

ファイルにキー/グループの関係がありkeys、ファイルに機能があると仮定するとfeatures、以下は入力に応じて期待される結果を取得します。

awk '{print $2}' keys | sort -u | xargs -i_group awk '{if($2=="_group")print $1}' keys | sort -u | xargs -i_key awk '{if ($3=="_key" && $2=="KEY")print $1}' features | sort -u | xargs -i_id awk '{if($1=="_id")print $0}' features

これは単なる解決策であり、必ずしも良い解決策ではなく、パフォーマンスの点では最悪の解決策である可能性もありますが、それでも解決策の 1 つです。

答え3

私は次のような短い解決策を見つけました:

grep -P "^\ +[`awk '$3==""{a[$1]=$2}; $2=="KEY" && $3 in a {printf "%s", $1}' \
<(cat keys features)`]" features

次のようなコマンドが生成されます。

grep -P "^\ +[ABD]" features

...ABD真ん中の-部分は、次のawk文でまとめられます

関連情報