else 명령의 결과는 효과가 없습니다.

else 명령의 결과는 효과가 없습니다.

이 스크립트는 작동합니다.

$cat list

IP address=192.3.xx.xx
IP address=192.4.xx.xx
IP address=192.19.xx.xx
IP address=192.22.xx.xx
$ cat myscript.sh

for i in `cat list | cut -d= -f2  | egrep '192.3|192.4'`
do
    if [ $? -eq 0 ]
    then
       echo $i
    else
       echo "no IP found"
    fi
done
$ ./myscript.sh

192.3.xx.xx
192.4.xx.xx

하지만 192.3과 192.4를 192.8과 같은 다른 값으로 변경하면 다음과 같은 결과를 얻게 됩니다.

no IP found

스크립트는 아무것도 반환하지 않습니다.

귀하의 도움에 감사드립니다. 감사해요

답변1

따라서 있는 경우 cat list | cut -d= -f2 | egrep '192.8'의 출력은 egrep비어 있고 명령 대체는 비어 있는 것으로 확장됩니다. 루프 for에는 반복할 항목이 없으며 루프 본문은 실행되지 않으며 "찾을 수 없음" 메시지를 인쇄할 항목이 없습니다.

$?루프 본문의 시작 부분에서 테스트하는 것은 어쨌든 별 의미가 없습니다. 실제로 첫 번째 반복에서는 명령 대체의 종료 상태를 테스트하고 있지만 이후 반복에서는 테스트하고 있습니다.이전 반복의 마지막 명령, with는 그다지 유용하지 않을 수 있습니다. 여기서는 실패할 가능성 이 없지만 echo다른 작업을 수행하면 흥미로운 결과를 얻을 수 있습니다.

for i in `cat list | cut -d= -f2  | egrep '192.3|192.4'`
do
    if [ $? -eq 0 ]
    then
       # assume we're doing something more useful here
       echo "trying to do something with $i..."
       # but it happens to fail
       false
    else
       echo "no IP found"
    fi
done

출력은 다음과 같습니다

trying to do something with 192.3.xx.xx...
no IP found

조금 혼란 스럽습니다.


루프가 아무것도 찾지 못하는 경우 "or else" 부분을 실행하는 쉬운 방법은 다음과 같이 루프에 플래그를 설정하고 나중에 테스트하는 것입니다.

found=
key=192.8
for i in $(cat list | cut -d= -f2  | egrep "$key"); do
    found=1
    echo $i;
done
if [ -z "$found" ]; then
    echo nothing found
fi

이 경우에는 여전히 약간 어리석지만, 모든 루프가 for기본적으로 수행하는 작업은 egrep이미 인쇄하고 있던 것과 동일한 내용을 인쇄하는 것입니다(게다가 올바르게 작동하려면 토큰화에 의존하고 있지만 어쨌든 전역 문자가 없을 수도 있습니다). .

아마도 IP 주소를 사용하여 다른 작업을 하고 있을 것 같지만, 그냥 인쇄하려는 경우에는 출력을 직접 사용 egrep하고 종료 상태를 확인하여 일치하는 항목이 있는지 확인하는 것이 좋습니다.

key=192.8
if ! cat list | cut -d= -f2  | egrep "$key"; then
    echo "nothing found"
fi

또는 출력 라인을 배열로 읽어 처리합니다. Bash에서는 다음을 사용할 수 있습니다 readarray.

readarray -t ips < <(cat list | cut -d= -f2  | egrep "$key")
num=${#ips[@]}
if [ "$num" = 0 ]; then
    echo "zero items in list"
else 
    echo "found $num items"
fi
for ip in "${ips[@]}"; do
    echo "doing something with $ip..."
done

분할+for 루프와 크게 다르지 않지만 입력 요소 자체에 공백이나 와일드카드가 포함될 수 있는 경우에 더 안전합니다.

답변2

일반 텍스트 조작을 위한 필수 POSIX 도구(즉, 모든 Unix 시스템에서 사용 가능)는 입니다 awk. awk를 사용하십시오.

$ awk -F'=' '$2 ~ /^192\.[34]\./{f=1; print $2} END{ if (!f) print "no IP found"; exit !f }' list
192.3.xx.xx
192.4.xx.xx

$ awk -F'=' '$2 ~ /^192\.[8]\./{f=1; print $2} END{ if (!f) print "no IP found"; exit !f }' list
no IP found

언급할만한 다른 사항:

  • egrep약 20년 전에 더 이상 사용되지 않습니다. 대신 grep -E사용하지 마세요.
  • @ChrisDavies의 의견이 문제라는 것을 이해하지 못하는 것 같습니다.그는 지적했다귀하의 질문에 여전히 존재합니다.
  • cat list | cut -d= -f2연합 대학, 또는 이어야 하며 cut -d= -f2 list, cut -d= -f2 < list원할 경우 가 될 수도 있습니다 <list cut -d= -f2.
  • echo $iecho "$i"( 참조https://mywiki.wooledge.org/Quotes).
  • 항상 코드를 실행하세요.http://shellcheck.net쉘에 더 익숙해질 때까지.

관련 정보