2

I have a file named file.txt. The content of the file is as follows

sunday
monday
tuesday

I wrote the below script and it loops just fine if the grep cannot find the pattern that was mentioned

until cat file.txt | grep -E "fdgfg" -C 9999; do sleep 1 | echo "working..."; done

But my requirement is that the above script should loop until the text mentioned in the grep pattern disappears in the file.txt

I tried to use the L flag with grep. But it didn't work.

until cat file.txt | grep -EL "sunday" -C 9999; do sleep 1 | echo "working..."; done
  • So essentially , you want to print everything until the line that has "sunday" in it , correct ? – Sergiy Kolodyazhnyy Nov 16 '16 at 1:49
  • @Serg: No. I want to execute the do part until the grep part does not find sunday in the file.txt. Assume that some process modifies the file.txt and removed sunday from the file while the until..... statement is running – Damien-Amen Nov 16 '16 at 1:52
10

From grep man page:

EXIT STATUS
   Normally the exit status is 0 if a line is selected, 1 if no lines were
   selected, and 2 if an error occurred.  However, if the -q or --quiet or
   --silent is used and a line is selected, the exit status is 0  even  if
   an error occurred.

So if a line is present, the exit status is 0. Since on bash 0 is true (because the standard "successful" exit status of programs is 0) you should actually have something like:

#!/bin/bash

while grep "sunday" file.txt > /dev/null;
do
    sleep 1
    echo "working..."
done

Why exactly are you piping sleep 1 to echo? Though it works, it doesn't make much sense. If you wanted them inline you could just write sleep 1; echo "working..." and if you wanted the echo to run before the delay, you could have it before the sleep call like echo "working..."; sleep 1.

  • 1
    Just use grep "sunday" file.txt ,avoid useless use of cat – Sergiy Kolodyazhnyy Nov 16 '16 at 1:55
  • Also, grep can be redirected to /dev/null or use --quiet option – Sergiy Kolodyazhnyy Nov 16 '16 at 1:56
  • 1
    Another cat saved from cat abuse! Thanks @Serg. I corrected the code, just a note: --quiet option would actually break the code here, because then the exit status would always be 0. Redirecting the output to /dev/null should do it though! – IanC Nov 16 '16 at 2:00
  • Perfect. Thanks a lot. That worked like a charm :) – Damien-Amen Nov 16 '16 at 2:06
  • 1
    If you wanna have the reverse functionality (loping while it's NOT there) just replace while with until keyword. – keiki Dec 17 '18 at 15:28
1

This should do the job:

#!/bin/bash
while true ; do 
  echo "Working..."
  result=$(grep -nE 'sunday' file.txt) # -n shows line number
  echo "DEBUG: Result found is $result"
  if [ -z "$result" ] ; then
    echo "COMPLETE!"
    break
  fi
  sleep 1
done

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.