awkを使用して、ある変数の特定の列の各行の数を、他の変数の2つの特定の列のすべての行について確認します。

awkを使用して、ある変数の特定の列の各行の数を、他の変数の2つの特定の列のすべての行について確認します。

awkある変数の特定の列の各行の数字を他の変数の2つの特定の列のすべての行と比較して確認し、パラメータと一致する最初の変数の行を保持するために使用する必要があります。

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

例は次のとおりです。

  • ${ListToCheckFrom}任意の行>列2と<列3の数字の場合は、列2の行のみを印刷するとします。${ListToCheckAgainst}

  • 入力例:

    ListToCheckFrom="C,2  
    C,22  
    C,12  
    hr,15"
    
    ListToCheckAgainst="C1,25,50  
    hr1,22,30  
    r,12,18  
    C,15,44"  
    
  • 予想出力:

    C,22  
    hr,15
    

答え1

質問にタグを付けたので、bashプロセス置換を活用して入力ファイルなどのシェル変数を読み取ることができます。次のスクリプトフラグメントは、次のことを行う必要があります。

#!/bin/bash

ListToCheckFrom="C,2  
C,22  
C,12  
hr,15"

ListToCheckAgainst="C1,25,50  
hr1,22,30  
r,12,18  
C,15,44"

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")

これはecho、最初の入力ファイルの内容と2番目の入力ファイルの内容を指定します。現在処理中の「ファイル」を内部的に区別できるように、各ファイルが「開いている」か、その前に変数を設定します。$ListToCheckAgainstecho$ListToCheckFromawklistconstrchkawk

  • で「制約」を処理するときは、$ListToCheckAgainst単に列2と3で指定された「下限」と「上限」をそれぞれ配列とlow格納しますhigh。それ以外の場合は、すぐに次の入力ラインに処理をスキップします。
  • 確認するリストを処理するときに、以前に$ListToCheckFrom登録されたすべての範囲を検索し、列2がその範囲の1つに属することがわかったら、それを印刷します(そしてすぐに次の入力行に処理をスキップします)。

データがシェル変数ではなく「物理」ファイルに保存されている場合は、プロセス置換の代わりにファイル名をコマンドライン引数として使用できます。

答え2

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

ListToCheckFrom='C,2
C,22
C,12
hr,15'

ListToCheckAgainst='C1,25,50
hr1,22,30
r,12,18
C,15,44'

awk '
    BEGIN { FS="," }
    NR==FNR {
        begs2ends[$2] = $3
        next
    }
    {
        for ( beg in begs2ends ) {
            beg += 0
            end = begs2ends[beg]+0
            if ( (beg < $2) && ($2 < end) ) {
                print
                next
            }
        }
    }
' <(printf '%s\n' "$ListToCheckAgainst") <(printf '%s\n' "$ListToCheckFrom")

$ ./tst.sh
C,22
hr,15

関連情報