While read line with grep

29,059

Solution 1

You can also use && and || operators :

while read line; do
         grep -q "$line" file_to_check  && echo "$line found in file_to_check" || echo "$line not found in file_to_check"
done < inputfile > result.txt

The -q parameter of the grep just outputs a status code :

  • if $line is found, it outpouts 0 (True) the command after && will be evaluated
  • if not found, it outputs 1 (False) the command after || will evaluated

Solution 2

You can rewrite your final solution into

# Do not need this thanks to tr: file=$(dos2unix inputs.txt)

# Use -r so a line with backslashes will be showed like you want
while read -r line
do 
   # Not empty? Check with test -n
   if [ -n "$(grep "${line}" filename)" ]; then 
      echo "found: ${line}"
   else
      echo "not found: ${line}"
   fi 
done < <(tr -d "\r" < "${file}")
Share:
29,059
Joshua
Author by

Joshua

Updated on April 24, 2020

Comments

  • Joshua
    Joshua about 4 years

    I am trying to report lines found using grep and while.

    I know you can use the following to compare a list of strings from inputs.txt and find them in your target file like so:

    grep -f inputs.txt file_to_check
    

    What I want is to read each line of the inputted strings and grep them individual in a loop.

    So I have tried the following methods:

    cat inputs.txt | while read line; do if grep "$line" filename_to_check; then echo "found"; else echo "not found"; fi; done
    

    This returns nothing when I redirect the output to a file.

    while read line
    do
    if grep "$line" file_to_check
      then echo "found"
    else 
      echo "not found"
    fi
    done < inputs.txt
    

    Same as the first one but from what I found is better to do.

    I know it iterates line by line because I can replace grep with echo $line and it prints each line; but either method doesn't return anything like grep -f above, instead it shows:

    not found
    not found
    not found
    .
    . etc.
    

    So what I'm looking for is something where it will iterate through each line and check it via grep using an if statement to determine if grep has actually found it or not. I know I may not have all proper logic but the output for what I want should look something like:

    Found *matching line in file_to_check* 
    Found *matching line in file_to_check*
    Not Found $line *(string that does not match)*
    .
    . etc.
    
  • Joshua
    Joshua about 8 years
    Thanks I found the file special carriage returns that grep did not know how to handle. So I copied the content into another test file via VIM and it reported what I wanted. @Skyler, your example helped but it gave some weird output and even test it with my new file that worked after testing. The out put using: while read line; do if [ $(grep "$line" file_to_check) != "" ]; then echo "found: $line" else echo "not found: $line" fi done < inputs.txt gave bash: [: !=: unary operator expected not found: item1 bash: [: !=: unary operator expected not found: item2 etc.
  • Skyler
    Skyler about 8 years
    My apologies @Joshua, the $(command) should have been surrouded by double quotes, answer updated.
  • Barmar
    Barmar about 8 years
    @Joshua If the file contains carriage returns, use dos2unix to convert it to normal Unix newlines.
  • Joshua
    Joshua about 8 years
    Thanks, that was my bad on the double quotes there. I think I have solved my solution and will look into dos2unix. I started using cat inputs.txt | tr -d '\r' > newinputs.txt which worked well too.
  • William Pursell
    William Pursell about 7 years
    Do not do if [ "$(grep "$line" filename)" != "" ]. Just do if grep -q "$line" filename.