3

/home/errorcodes contains:

421 RP-001
421 RP-002
421 RP-003
550 SC-001
550 SC-002
550 SC-003
550 SC-004
550 DY-001
550 DY-002
550 DY-001
550 OU-001
550 OU-002

Script:

#!/bin/bash

Elogs=/home/elogs.txt
Errors=/home/errorcodes
for i in `cat $Errors`; do
    #Get Error Logs
    grep "$i" /home/eximlog >> $Elogs
done

Debug:

+ cat /home/errorcodes
+ for i in '`cat $Errors`'
+ grep 421 /home/eximlog
+ for i in '`cat $Errors`'
+ grep RP-001 /home/eximlog
+ for i in '`cat $Errors`'
+ grep 421 /home/eximlog
+ for i in '`cat $Errors`'
+ grep RP-002 /home/eximlog
+ for i in '`cat $Errors`'
+ grep 421 /home/eximlog
+ for i in '`cat $Errors`'
+ grep RP-003 /home/eximlog
+ for i in '`cat $Errors`'
+ grep 550 /home/eximlog
+ for i in '`cat $Errors`'
+ grep SC-001 /home/eximlog
+ for i in '`cat $Errors`'
+ grep 550 /home/eximlog
+ for i in '`cat $Errors`'
+ grep SC-002 /home/eximlog
+ for i in '`cat $Errors`'
+ grep 550 /home/eximlog
+ for i in '`cat $Errors`'
+ grep SC-003 /home/eximlog
+ for i in '`cat $Errors`'
+ grep 550 /home/eximlog
+ for i in '`cat $Errors`'
+ grep SC-004 /home/eximlog
+ for i in '`cat $Errors`'
+ grep 550 /home/eximlog
+ for i in '`cat $Errors`'
+ grep DY-001 /home/eximlog
+ for i in '`cat $Errors`'
+ grep 550 /home/eximlog
+ for i in '`cat $Errors`'
+ grep DY-002 /home/eximlog
+ for i in '`cat $Errors`'
+ grep 550 /home/eximlog
+ for i in '`cat $Errors`'
+ grep DY-001 /home/eximlog
+ for i in '`cat $Errors`'
+ grep 550 /home/eximlog
+ for i in '`cat $Errors`'
+ grep OU-001 /home/eximlog
+ for i in '`cat $Errors`'
+ grep 550 /home/eximlog
+ for i in '`cat $Errors`'
+ grep OU-002 /home/eximlog

Why does the loop read all codes like "421" and "RP-001" separately? And bring duplicate result. Grep should consider codes a single string like: "421 RP-001" And debugging should be like this:

+ for i in 'cat $Errors'
+ grep 421 RP-001 /home/eximlog
    ︙

1 Answer 1

7

The shell will perform word splitting on $(cat $Errors). That is why you get one word at a time instead of one line at a time.

You want a while read... loop:

while read -r line; do
    #Get Error Logs
    grep "$line" /home/eximlog >> $Elogs
done <"$Errors"

read is line oriented: it reads one line at a time.

Or, this may work for you and it doesn't need any looping at all:

 grep -f "$Errors" /home/eximlog

The -f options tells grep to read patterns from a file, one pattern per line.

Also, it looks to me like your error code patterns are fixed strings not regular expressions. In that is the case, to avoid unpleasant surprises, add the -F option to grep:

 grep -Ff "$Errors" /home/eximlog
2
  • 2
    Yes grep -f "$Errors" /home/eximlog works for me. thanks @John1024 Commented Jun 8, 2016 at 6:45
  • 1
    was returning only one line for me, and I discovered this is due to CRLF line endings in the source file, so make sure you have it converted to Unix EOL Commented Jul 26, 2022 at 15:58

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.