コンテキスト
フォローアップの質問です私は以前尋ねた質問です。。驚くべき助けを受けるまでは、知らなかった新しい詳細/問題が現れました。カミール・マコロフスキーそして男の名前。私は説明と簡潔さのために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
行を追加しようとしましたが、awk
Home#が単独であれば印刷してスペースを追加しました。私は以下を追加しました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: ss11
480 sam
956 sam
956 sample rd N: 53
また、除外の始めに別のifを追加しようとしましたが、単一の家番号がorほど一定ではないことにscript.sh
気づきました。odd
even
追加のヘルプやアドバイスをいただきありがとうございます。範囲が正常に見つかったら、個々の住宅番号を何とか除外する必要があることを知っていますが、これを行う方法を理解するのが困難です。
答え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
行われ、フィルタ基準はによって行われます)。grep
awk
civic
- 最初のフィールドが完全に数値ではない場合は、範囲または数値がなく、行が一致することを意味します。
- そうではなく、2番目のフィールドが完全に数字ではない場合、項目は1桁の数字で始まります。この場合、
civic
数値が一致する場合にのみ行が一致します。 - 最初のケースと2番目のケースの両方が真でない場合は範囲と見なされます。行は
civic
範囲内にある場合にのみ一致します。