문맥
후속 질문입니다예전에 물어본 질문인데. 놀라운 도움을 받기 전까지는 몰랐던 새로운 세부 사항/문제가 나타났습니다.카밀 마코로프스키그리고남자 이름. 나는 설명과 간결함 때문에 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
, 집 #이 단독으로 있으면 인쇄하고 공백을 추가했습니다. 나는 다음을 추가했다 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
는 세 가지 경우를 고려합니다(필터 기준은 이미 에 의해 street
수행되었으며 필터 기준은 에 의해 수행됨 ).grep
awk
civic
- 첫 번째 필드가 완전히 숫자가 아닌 경우 범위나 숫자가 없고 행이 일치함을 의미합니다.
- 그렇지 않고 두 번째 필드가 완전히 숫자가 아닌 경우 항목이 한 자리 숫자로 시작한다는 의미입니다. 이 경우
civic
숫자가 일치하는 경우에만 행이 일치합니다. - 첫 번째 경우와 두 번째 경우 모두 참이 아닌 경우 범위로 간주됩니다. 행은
civic
범위 내에 있는 경우 에만 일치합니다 .