Wang Xiaoyu
Wang Xiaoyu

Reputation: 387

How to find a line in a file?

How to find a line in given file by using shell script? File name is /etc/crontab.The content is here:

17 */1 * * * root /opt/first.sh
*/1 * * * * root /opt/second.sh

grep -q "*/1 * * * * root /opt/second.sh" /etc/crontab

I have used above command and got $? code is 1 rather than 0.

So what's wrong?. If you have another way, let me know. thanks!

Upvotes: 1

Views: 242

Answers (3)

John1024
John1024

Reputation: 113994

If you want to match a fixed string, the easiest thing to do is to use the -F option:

$ grep -F "*/1 * * * * root /opt/second.sh" crontab
*/1 * * * * root /opt/second.sh

Or, to get the exit code only, add -q:

$ grep -qF "*/1 * * * * root /opt/second.sh" crontab ; echo code=$?
code=0

Normally, grep interprets the search string as a regular expression. This means that characters like * or . or + are active. -F turns that feature off so that the search string is treated as just a plain fixed string.

The meaning of */ * * * * root /opt/second.sh

Observe what */ * * * * root /opt/second.sh matches:

$ echo '*/ root /opt/second.sh' | grep '*/ * * * * root /opt/second.sh'
*/ root /opt/second.sh

But, the following does not match:

$ echo '*/ * root /opt/second.sh' | grep '*/ * * * * root /opt/second.sh'
$

* is treated as zero or more of the preceding characters. So, * * * * matches zero or more spaces. It does not match stars.

grep treats a star at the beginning of a regex specially. Since * means zero or more of the preceding character and a * at the beginning has no preceding character, it makes no sense. Many programs would give an error. grep, by contrast, interprets such as * as, in this special case, a literal star.

Upvotes: 1

Mischa
Mischa

Reputation: 1333

To match a literal asterisk you have to tell grep that this asterisk is literal.

For that you need to encapsulate the asterisk with [ and ]
It'll look like this now:

grep -q "[*]/1 [*] [*] [*] [*] root /opt/second.sh" /etc/crontab

Upvotes: 1

Shravan Yadav
Shravan Yadav

Reputation: 1317

  • is treated as wild character in unix. Even in "*", * will do its job.

use

grep -q "\*/1 \* \* \* \* root /opt/second.sh" /etc/crontab ## will grep correct line and give success

it will correct otherwise

grep -q "*/1 * * * * root /opt/second.sh" /etc/crontab  ## will grep nothing and still return success code

Upvotes: 2

Related Questions