Вопрос

У меня есть следующий скрипт

cat $1 | while read line
do
    line=`echo $line | tr "[:lower:]" "[:upper:]"`

    if [ "`echo $line | cut -f1 -d:`" = "foo" ] && \
       [ "`echo $line | cut -f2 -d:`" = "bar" ]; then
        echo 'exsist'
        exit 1;
    fi
done

все работает до эха, а затем, когда сценарий достигает выхода, он не работает и продолжает работать.Есть идеи.

Спасибо

Это было полезно?

Решение

Вам не нужна обратная косая черта — это не оболочка C.

Проблема в том, что цикл while находится во вложенной оболочке, которая завершается, но поскольку он запускается как вложенная оболочка, основной сценарий продолжает выполняться.

В контексте, вероятно, самое простое решение:

while read line
do
    line=`echo $line | tr "[:lower:]" "[:upper:]"`
    if [ "`echo $line | cut -f1 -d:`" = "foo" ] &&
       [ "`echo $line | cut -f2 -d:`" = "bar" ]; then
        echo 'exist'
        exit 1
    fi
done < $1

Если вам нужно обработать несколько файлов («cat «$@»» вместо «cat $1»), вам придется работать намного сложнее немного сложнее:

cat "$@" |
while read line
do
    line=`echo $line | tr "[:lower:]" "[:upper:]"`
    if [ "`echo $line | cut -f1 -d:`" = "foo" ] &&
       [ "`echo $line | cut -f2 -d:`" = "bar" ]; then
        echo 'exist'
        exit 1
    fi
done
[ $? != 0 ] && exit 1

Это проверяет статус завершения конвейера, состоящего из «cat» и « while», который является статусом завершения цикла while, который в примере будет равен 1, если «foo:bar» найден в начале линия.

Конечно, есть и другие способы обнаружить это, например:

grep -s -q "^foo:bar:" "$@" && exit 1

При этом выполняется гораздо меньше команд, чем в версии с циклом.(Если вам также необходимо разрешить использование '^foo:bar$', используйте egrep вместо обычного grep.)

Другие советы

Вы переводите свой текст из нижнего регистра в верхний регистр, но затем проверяете его на нижний регистр, поэтому вы никогда не доберетесь до выхода.

поскольку вы хотите преобразовать каждую строку в верхний регистр, вы можете сделать это следующим образом

#!/bin/sh

tr '[:lower:]' '[:upper:]' < file | while IFS=":" read -r a b c
do
    case "$a $b" in
        "FOO BAR" ) echo "exist";exit;;
        *) echo "$a $b";;
    esac
done

ИЛИ вы можете сделать это с помощью awk (nawk для Solaris)

nawk -F":" '
topper($1)=="FOO" && topper($2)=="BAR"{
    print "exist"
    exit
}
{
    print topper($0)
}
' file

Вы можете сделать свои условия нечувствительными к регистру, добавив shopt -s nocasematch выше теста.Чтобы вернуть значение с учетом регистра: shopt -u nocasematch.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top