数値範囲が正常に見つかった場合は、文字列を除外します。自宅住所のテキストで文字列を検索する前の質問に関する次の質問

数値範囲が正常に見つかった場合は、文字列を除外します。自宅住所のテキストで文字列を検索する前の質問に関する次の質問

コンテキスト

フォローアップの質問です私は以前尋ねた質問です。。驚くべき助けを受けるまでは、知らなかった新しい詳細/問題が現れました。カミール・マコロフスキーそして男の名前。私は説明と簡潔さのためにKamil Machorovskyの答えを選択しましたが、両方の答えは当時私が探していたものを達成しました。このスクリプトの正確な理由は、前の質問で説明されました。

これは何ですか?

カミール・マコロフスキーコードは次のとおりですscript.sh

#! /bin/bash

civic="$1"
street="$2"

if [ "$((civic%2))" = 1 ]; then
   exclude=" even "
else
   exclude=" odd "
fi

</path/to/addresses.txt grep -E "(^| )$street" \
   | grep -v "$exclude" \
   | awk -F '[ -]' -v civic="$civic" '
      {if ($1 !~ /^[0123456789]*$/ || $2 !~ /^[0123456789]*$/) print
       else if (civic>=$1 && civic<=$2) print}
     '

このコードを使用すると、自宅番号と通り名を渡すことができます。addresses.txt住所範囲と通り名の前に住所番号がない住所を確認して、正しい文字列を検索して返します。以下は、addresses.txt突然変異事例を示す例(匿名)です。

1 fastest rd S: 99
2-58 fastest rd N: 98
42 fake st: ss12
1 test st: 1
2-199 test st: 2
200-300 even test st: 22
301-399 odd test st: 33
example dr N: ss5
example dr S: 226
956 sample rd N: 53
976-998 even sample rd N: 54
340-500 even sample rd S: ss11
401-487 odd sample rd S: 45

./script.sh 1 fasそのデータを使用して、次の出力を実行して取得できます。これは完璧です。

1 fastest rd s: 99

別の完璧な例./script.sh 42 fak

42 fake st: ss12

もう一つの良い例./script.sh 20 ex

example dr N: ss5
example dr S: 226

Nここではdrとsumの例を返しますS。これは私にとって重要で動作するために必要な方法です。

どのような問題が発生しましたか?

元の質問では、addresses.txt範囲(例::)ではなく家の番号のみを含む文字列をサンプルに含めることは無視されました1 test st: 1。データのこの部分を設定するために、addresses.txt上記の例の関連文字列は次のとおりです。

1 fastest rd S: 99
2-58 fastest rd N: 98
1 test st: 1
2-199 test st: 2
956 sample rd N: 53
976-998 even sample rd N: 54
340-500 even sample rd S: ss11
401-487 odd sample rd S: 45

スクリプトの現在の状態(つまり)で./script.sh 89 tes出力を実行すると、次のようになります。

1 test st: 1
2-199 test st: 2

この行に注意してください1 test st: 1。これは2-199 test st: 2私の検索とよりよく一致するので、その項目だけを返したいと思います。89 tes

他の例./script.sh 483 sam

956 sample rd N: 53
401-487 odd sample rd S: 45

483を奇数で正常に識別し、範囲を401-487 odd sample rd S: 45含めるのではなく範囲と一致させます。340-500 even sample rd S: ss11ただし、956 sample rd N: 53私の検索と一致しないが返されます。

私はこの問題を解決しようとします。

カミール・マコロフスキーawkスクリプトのこの部分を「完全に数字ではなく最初のフィールドを見つけて、距離名の前に範囲、単一値、または何もないことを確認する」に変更できることを提案します。私は番号を見つけようとする別のelse if行を追加しようとしましたが、awkHome#が単独であれば印刷してスペースを追加しました。私は以下を追加しましたelse if (civic =~ /^[0123456789]\s$/) print}

</path/to/addresses.txt grep -E "(^| )$street" \
   | grep -v "$exclude" \
   | awk -F '[ -]' -v civic="$civic" '
      {if ($1 !~ /^[0123456789]*$/ || $2 !~ /^[0123456789]*$/) print
       else if (civic>=$1 && civic<=$2) print
       else if (civic =~ /^[0123456789]\s$/) print}
     '

この種の表現は私にとって新しいものであるため、構文エラーが発生するのを防ぐことができないため、まったく驚かない。反転と行を試みましたが、($1 !~ /^[0123456789]*$/ || $2 !~ /^[0123456789]*$/)検索時にのみ返されました(civic>=$1 && civic<=$2)。しかし、検索は発生しませんでした。340-500 even sample rd S: ss11480 sam956 sam956 sample rd N: 53

また、除外の始めに別のifを追加しようとしましたが、単一の家番号がorほど一定ではないことにscript.sh気づきました。oddeven

追加のヘルプやアドバイスをいただきありがとうございます。範囲が正常に見つかったら、個々の住宅番号を何とか除外する必要があることを知っていますが、これを行う方法を理解するのが困難です。

答え1

この修正されたスクリプトは単一の数値のサポートを追加します。

#! /bin/bash

civic="$1"
street="$2"

if [ "$((civic%2))" = 1 ]; then
   exclude=" even "
else
   exclude=" odd "
fi

</path/to/addresses.txt grep -E "(^| )$street" \
   | grep -v "$exclude" \
   | awk -F '[ -]' -v civic="$civic" '
      {if ($1 !~ /^[0123456789]*$/) print
       else if ($2 !~ /^[0123456789]*$/) {if (civic==$1) print}
       else if (civic>=$1 && civic<=$2) print}
     '

ここで、コードawkは3つのケースを考慮します(フィルタ基準はすでにによってstreet行われ、フィルタ基準はによって行われます)。grepawkcivic

  1. 最初のフィールドが完全に数値ではない場合は、範囲または数値がなく、行が一致することを意味します。
  2. そうではなく、2番目のフィールドが完全に数字ではない場合、項目は1桁の数字で始まります。この場合、civic数値が一致する場合にのみ行が一致します。
  3. 最初のケースと2番目のケースの両方が真でない場合は範囲​​と見なされます。行はcivic範囲内にある場合にのみ一致します。

関連情報