AWK: ヘッダーのない入れ子になった条件付き行サブセット

AWK: ヘッダーのない入れ子になった条件付き行サブセット

私は非常に特定の問題を抱えており、awkを使用してサブセット条件について多くを見つけることができましたが、どちらも私の状況に一般化できるほど明確なコードを提供しませんでした。 「keys」ファイルと「features」ファイルがあります。タイトルなし。 「keys」テーブルには、次のように、KEYとGROUP(それぞれ最初の列と2番目の列)の2つの変数が含まれています。

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

"features"ファイルには、このようなウィジェットの機能のリストが含まれています(それぞれID、FEATURE、VALUEの最初、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

これは単なる解決策であり、必ずしも良い解決策ではなく、パフォーマンスが最良ではないかもしれませんが、それでも解決策です。

答え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文で収集されます。

関連情報