숫자 범위가 성공적으로 발견되면 문자열을 제외합니다. 집 주소 텍스트에서 문자열 검색에 대한 이전 질문에 대한 후속 질문

숫자 범위가 성공적으로 발견되면 문자열을 제외합니다. 집 주소 텍스트에서 문자열 검색에 대한 이전 질문에 대한 후속 질문

문맥

후속 질문입니다예전에 물어본 질문인데. 놀라운 도움을 받기 전까지는 몰랐던 새로운 세부 사항/문제가 나타났습니다.카밀 마코로프스키그리고남자 이름. 나는 설명과 간결함 때문에 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: 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는 세 가지 경우를 고려합니다(필터 기준은 이미 에 의해 street수행되었으며 필터 기준은 에 의해 수행됨 ).grepawkcivic

  1. 첫 번째 필드가 완전히 숫자가 아닌 경우 범위나 숫자가 없고 행이 일치함을 의미합니다.
  2. 그렇지 않고 두 번째 필드가 완전히 숫자가 아닌 경우 항목이 한 자리 숫자로 시작한다는 의미입니다. 이 경우 civic숫자가 일치하는 경우에만 행이 일치합니다.
  3. 첫 번째 경우와 두 번째 경우 모두 참이 아닌 경우 범위로 간주됩니다. 행은 civic범위 내에 있는 경우 에만 일치합니다 .

관련 정보