user3634853
user3634853

Reputation: 13

How to use GREP command to read more then one line in file

I am stumped. How can I use the GREP command to read more then one line in a file. this is what I have worked on so far but only reads one line in file. If I add another line that's when it says can't read .... I am using Linux shell. I have been trying to research this for the past 2 days and still nothing. Any help would be welcomed. Thanks.

(

echo;echo -ne "Checking Firewall INPUT chain for entry ... ";

if ! iptables -vnL INPUT | grep `cat $_file` >/dev/null ; then
    echo "Not Found!"

    for IP in `cat $_scriptpath/tmp/badip.cache`
   do

    iptables -A INPUT -s $IP -j badipblock

   done

    echo External IP : $IP has been banned! $_DATE > $_scriptpath/log/badip_fw_$_DATE.log
else
echo "Entry already exists"
fi
echo;

)

Upvotes: 0

Views: 180

Answers (1)

Charles Duffy
Charles Duffy

Reputation: 295687

How to read a list of patterns to match from a file in grep

grep -f "$_file"

...will treat each line of $_file as a pattern, and will match any of those patterns. (The usual flags can be used to modify how those patterns are interpreted -- -E for ERE, -F for fixed strings, etc).


Why the original code failed

The immediate cause is this:

grep `cat $_file`

In this apparently-innocuous code, you're actually doing the following:

  • Splitting the contents of the variable $_file on the characters found in the shell setting IFS (by default spaces, tabs and newlines) into more than one word
  • Treating each of those words as a separate glob expression; if any can be parsed as a glob, then replacing it with one word for each matching entry on the local filesystem.
  • Passing the words resulting from that stage each as a separate argument to cat.
  • Letting cat try to open a file named for each such word (unless they start with dashes, in which case it would treat them as option flags) and concatenate together their output.
  • Capturing that concatenated output, string-splitting it again (as above), glob-expanding it again (as above), and then appending the resulting words to the command line for grep

...so, then, what does that do? Let's say that the output from cat only evaluates to one word, foo:

grep foo

...so, we're looking for foo in our stdin streams. Let's say, by contrast, that it evaluates to two words, foo and bar:

grep foo bar

This is doing something entirely different: It's treating foo as a string to search for -- but it's treating bar as the name of the file to search in, ignoring anything which you piped as stdin.


Some references to follow going forward:

Upvotes: 2

Related Questions