Question

I have the following script

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

everything works up to echo and then when the script hits exit it does not and keeps going. Any ideas.

Thanks

Was it helpful?

Solution

You don't need that backslash - this is not the C shell.

The problem is that the while loop is in a sub-shell, which exits, but because it is run as a sub-shell, the main script continues.

In the context, the simplest fix is probably:

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

If you have to process multiple files ('cat "$@"' instead of 'cat $1'), then you have to work a lot harder bit harder:

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

This checks the exit status of the pipeline consisting of 'cat' and 'while', which is the exit status of the 'while' loop, which will be 1 in the example if 'foo:bar' is found at the start of a line.

Of course, there are other ways to detect that, such as:

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

This executes a lot less commands than the loop version. (If you need to allow for '^foo:bar$' as well, use egrep instead of plain grep.)

OTHER TIPS

You're translating your text from lower case text to upper case text, but then testing against lower case, so you never get to the exit.

since you want to convert to upper case for every line, you can do it like this

#!/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

OR you can do it with just awk(nawk for Solaris)

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

You can make your conditionals case-insensitive by adding shopt -s nocasematch above the test. To set things back to case-sensitive: shopt -u nocasematch.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top