awkを使用して、ある変数の特定の列セット内の各行に関する情報を、他の変数の3つの特定の列のすべての行について確認します。

awkを使用して、ある変数の特定の列セット内の各行に関する情報を、他の変数の3つの特定の列のすべての行について確認します。

今日は以前にも同様の質問をしましたが、コマンドのパラメータを増やす必要があることに気づきました。他のパラメータを使用してコマンドを編集しましたが、次のパラメータを使用すると成功率が低下する理由がわかりません。これが私が解決しようとしている(そして失敗している)問題です。

awkある変数の特定の列セットの各行の情報を使用して、別の変数の2つの特定の列のすべての行を確認し、パラメータと一致する最初の変数に行を保持する必要があります。

これまで、私は強力なコマンドでawkこれを実行しようとしましたが、失敗しました。明らかに、外部ループでこれを行うことができますが、確認する行が数百または数千個あるため、非常に遅くなります。この問題についてご協力いただきありがとうございます。私はいつもawkの使用を改善するために努力しています。したがって、解決策があれば、私が学び、改善できるように説明があればいいでしょう。

例は次のとおりです。

  • ${ListToCheckFrom}列2> =および列3 <=行の対応する列である場合にのみ行を印刷するとします${ListToCheckAgainst}。また、の列1は${ListToCheckFrom}次の列1と同じでなければなりません。${ListToCheckAgainst}

  • 入力例:

ListToCheckFrom="r,2,3
C,22,24
C,12,13
C,51,59
C,15,20
C,13,18"
        
ListToCheckAgainst="C,25,50
C,22,30
C,12,18
C,15,17
C,1,12
C,60,200"

  • 予想出力:
C,22,24  
C,12,13
C,15,20
C,13,18
  • 私が試したことは、今日私が尋ねるより簡単な質問に対する答えに基づいています(@ AdminBeeに感謝します)。
awk -F',' 'list=="constraints"{n++; low[n]=$2;high[n]=$3;c[n]=$1;next}
           {for (i=1;i<=n;i++) {if (($1==c[i])&&($2>=low[i]&&$2<=high[i])||($3>=low[i]&&$3<=high[i])) {print;next};}}' list=constraints <(echo "$ListToCheckAgainst") list=check <(echo "$ListToCheckFrom")

私はUbuntuを使用しています。

ベストアンサー1

確立されたもう一つの答え前の質問に戻りました。

$ cat tst.sh
#!/usr/bin/env bash

ListToCheckFrom="r,2,3
C,22,24
C,12,13
C,51,59
C,15,20
C,13,18"

ListToCheckAgainst="C,25,50
C,22,30
C,12,18
C,15,17
C,1,12
C,60,200"

awk '
    BEGIN { FS="," }
    NR==FNR {
        vals[NR] = $0
        next
    }
    {
        for ( nr in vals ) {
            split(vals[nr],v)
            if ( (v[1] == $1) && ( (v[2] <= $2) && ($2 <= v[3]) ) ) {
                print
                next
            }
        }
    }
' <(printf '%s\n' "$ListToCheckAgainst") <(printf '%s\n' "$ListToCheckFrom")

$ ./tst.sh
C,22,24
C,12,13
C,15,20
C,13,18

修正についてお問い合わせいただいたスクリプトに関して、前の質問に対する回答は次のとおりです。

awk -F',' 'list=="constr"{n++; low[n]=$2;high[n]=$3;next}
           {for (i=1;i<=n;i++) {if ($2>low[i]&&$2<high[i]) {print;next};}}' \
           list=constr <(echo "$ListToCheckAgainst") \
           list=chk <(echo "$ListToCheckFrom")

これを改善する最初のステップは、読みやすくすることです。たとえば、awk 部分を実行し、gawk -o-その周囲にシェル部分を再度追加すると、次のような結果が得られます。

awk -F',' '
    list == "constr" {
            n++
            low[n] = $2
            high[n] = $3
            next
    }
    
    {
            for (i = 1; i <= n; i++) {
                    if ($2 > low[i] && $2 < high[i]) {
                            print
                            next
                    }
            }
    }
' \
list=constr <(echo "$ListToCheckAgainst") \
list=chk <(echo "$ListToCheckFrom")

新しい要件を満たすには、次のように変更するだけでよいことがわかります。

awk -F',' '
    list == "constr" {
            n++
            key[n] = $1
            low[n] = $2
            high[n] = $3
            next
    }
    
    {
            for (i = 1; i <= n; i++) {
                    if ( (key[i] == $1) && ($2 > low[i] && $2 < high[i]) ) {
                            print
                            next
                    }
            }
    }
' \
list=constr <(echo "$ListToCheckAgainst") \
list=chk <(echo "$ListToCheckFrom")

おすすめ記事