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