anandan ramar
anandan ramar

Reputation: 47

how to continue with the loop even though we use exit for a condition in shell script

I have a following list.txt file with the content

cat list.txt
one
two
zero
three
four

I have a shell script (check.sh) like below,

for i in $(cat list.txt)
do
if [ $i != zero ]; then
echo "the number is $i"
else
exit 1
fi
done

it gives output like below,

./check.sh
the number is one
the number is two

I want to have script which continue with the rest of the items in the list.txt, but it should not process zero and continue with the rest of item.
eg.

the number is one
the number is two
the number is three
the number is four

I tried using "return" but it did not work, gave error.

./check.sh: line 6: return: can only `return' from a function or sourced script

Upvotes: 1

Views: 935

Answers (1)

F. Hauri  - Give Up GitHub
F. Hauri - Give Up GitHub

Reputation: 71047

About exit (and return)

The command exit will quit running script. There is no way to continue.

As well, return command will quit function. There in no more way to continue.

About reading input file

For processing line based input file, you'd better to use while read instead of for i in $(cat...:

Simply try:

while read -r i;do
    if [ "$i" != "zero" ] ;then
        echo number $i
    fi
done <list.txt 

Alternatively, you could drop unwanted entries before loop:

while read -r i;do
    echo number $i
done < <( grep -v ^zero$ <list.txt)

Note: In this specific case, ^zero$ don't need to be quoted. Consider quoting if your string do contain special characters or spaces.

If you have more than one entries to drop, you could use

while read -r i;do echo number $i ;done < <(grep -v '^\(zero\|null\)$' <list.txt)

Alternatively, once input file filtered, use xargs:

If your process is only one single command, you could avoid loop by using xargs:

xargs -n 1 echo number < <(grep -v '^\(zero\|null\)$' <list.txt)

How to use continue in script

Maybe you are thinking about something like:

while read -r i;do
    if [ "$i" = "zero" ] ;then
        continue
    fi
    echo number $i
done <list.txt

Argument of continue is a number representing number of loop to shortcut.

Try this:

for i in {1..5};do
    for l in {a..d};do
        if [ "$i" -eq 3 ] && [ "$l" = "b" ] ;then
            continue 2
        fi
        echo $i.$l
    done
done

(This print 3.a and stop 3 serie at 3.b, breaking 2 loop level)

Then compare with

for i in {1..5};do
    for l in {a..d};do
        if [ "$i" -eq 3 ] && [ "$l" = "b" ] ;then
            continue 1
        fi
        echo $i.$l
    done
done

(This print 3.a , 3.c and 3.d. Only 3.b are skipped, breaking only 1 loop level)

Upvotes: 3

Related Questions