3

I am trying to write a shell which will fetch a set of data from table and write it to a text file whose name is result.txt . Now I will pick each line from this file and search it in a log file and check if it present or not. If it is not found in the log file I want to write it in a separate file say notfound.txt. I am working on a AIX server and getting this below error for the grep command. Can somebody please help me figure out what's wrong?

Here is my script,

while read -r LINE; do
    grep -q "$LINE" log.log 
    if [  $? -eq 0 ]
    then
       echo "$LINE" >> /home/notfound.txt
    fi
done  < result.txt

which gives me following output,

grep: Not a recognized flag: - Usage: grep [-r] [-R] [-H] [-L] [-E|-F] [-c|-l|-q] [-insvxbhwyu] [-p[parasep]] -e pattern_list... [-f pattern_file...] [file...]

Usage: grep [-r] [-R] [-H] [-L] [-E|-F] [-c|-l|-q] [-insvxbhwyu] [-p[parasep]] [-e pattern_list...] -f pattern_file... [file...]

Usage: grep [-r] [-R] [-H] [-L] [-E|-F] [-c|-l|-q] [-insvxbhwyu] [-p[parasep]] pattern_list [file...]

  • The name "notfound" seems contradictory. The script prints the lines which were found in the log. – tripleee Aug 18 '16 at 4:41
  • 1
    rather than assuming what you have in that two files, it would be better for us if you post sample content of these two files in your question. – Rahul Aug 18 '16 at 4:43
  • @tripleee looks like logic error.. I will fix that – Preeti Maurya Aug 18 '16 at 4:54
  • 2
    See also "Ungrep" - which patterns aren't matched for a more efficient way to do it. – Stéphane Chazelas Aug 18 '16 at 6:49
  • Note that to read a line with read, the syntax is IFS= read -r line. Without IFS=, blanks are stripped from the beginning and end of the line. – Stéphane Chazelas Aug 18 '16 at 7:31
7

Looks like $LINE contains a value which starts with a dash.

You can protect against this with

grep -q -e "$LINE"

More generally, most Unix commands allow -- to mark the end of options, and so any argument after this "end of options" option will be taken as a literal, non-option argument.

echo will have a problem, too; the portable solution is to switch to printf, which works fine with arguments which start with dashes, as long as it's not the first argument, which is a format string.

You should also avoid using uppercase variable names; these are reserved for system use.

Finally, scripts should almost never need to explicitly examine $? - this is already done by if, while and other control constructs.

if grep -q -e "$line" log.log; then
    printf '%s\n' "$line"
fi

As an optimization, placing the redirection outside the loop will make things a lot quicker.

while read -r line; do
    grep -q -e "$line" log.log && printf '%s\n' "$line"
done <results.txt >notfound.txt
  • 1
    These is also the -- parameter, which will not parse any further parameters with a leading hyphen as though they are switches. grep -q -- "$pattern" "$haystack". – DopeGhoti Aug 18 '16 at 4:37
  • @tripleee Thanks your response. Will the second option check for each and every line from results.txt in log.log ? Also with the word dash what are you referring to ? – Preeti Maurya Aug 18 '16 at 4:37
  • The dash character (aka hyphen, minus, ASCII 0x2d) is used to introduce options to Unix commands. To use it as a regular non-option argument, you need to disambiguate it somehow. – tripleee Aug 18 '16 at 4:40
  • @tripleee Can I possibly start reading my file possibly from the nth LIne and stop just at the second last line ? – Preeti Maurya Aug 18 '16 at 4:47
  • If you have a new question which is unrelated to this one, ask a new question. But yes, what you are describing can be done, though it sounds like you should be looking at Awk. I was actually thinking that you should probably be using Awk for this task as well. – tripleee Aug 18 '16 at 4:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.