1

I have written a script to search an .ini file for some specific word.

The .ini file has one of two different names, (let's say config.ini or configuration.ini), so I have to check in both.

I am doing it with the following if sentences by using logical OR:

HAS_SOME_WORD=FALSE
if [ "$(grep -v '^;\|^\[' "path_to_file/config.ini" | \
 grep -c '\\some_word')" -ge 1 ] \
 || [ "$(grep -v '^;\|^\[' "path_to_file/configuration.ini" | \ 
 grep -c '\\some_word')" -ge 1 ]; then 
 HAS_SOME_WORD=TRUE
else
 HAS_SOME_WORD=FALSE
fi

I am avoiding the lines starting by ";" or "[" as they must not be included in the desired search, while looking for the word "\some_word".

I want is to exclude the grep error messages when one of the two files does not exist, i.e:

grep: path_to_file/config.ini: No such file or directory

or:

grep: path_to_file/configuration.ini: No such file or directory

I have been able to avoid them by redirecting the output to /dev/null when executing the script:

./search_script.sh 2>/dev/null

However I would like to include this redirection in the if code itself, not when invoking the script.

How shall I implement that? Is there a more efficient way of doing what I'm trying?

I have tried to add the -q parameter to grep in order to avoid the error messages printed, but it had no effect. Also tried adding 2>/dev/null redirection at the end of each if sentence, but I'm afraid that I haven't applied the correct syntax.

agc
7,3634 gold badges25 silver badges54 bronze badges
asked Jan 30, 2017 at 14:17
2
  • Adding a 2>/dev/null redirection in each if branch should work. Can you show us exactly what you tried? Commented Jan 30, 2017 at 17:15
  • @JigglyNaga I tried it as follows: if [ "$(grep -v '^;\|^\[' "path_to_file/config.ini" | \ grep -c '\\some_word')" -ge 1 2>/dev/null ]; then (For both if's) Commented Jan 31, 2017 at 8:26

2 Answers 2

2

Since grep can search multiple files, and that -v and -c code can be simplified, try:

cd "path_to file"
if grep -qs '^[^;[].*\\some_word' config.ini configuration.ini ; then 
 # ...etc
fi
cd -

The grep options in long form:

grep --quiet --no-messages '^[^;[].*\\some_word' \
 config.ini configuration.ini 

The OP code -v (or --invert-match) and 2nd grep are needless, because a regexp like ^[^;[] can do it in one shot. From man grep:

A bracket expression is a list of characters enclosed by [ and ]. It matches any single character in that list; if the first character of the list is the caret ^ then it matches any character not in the list.

answered Jan 30, 2017 at 16:43
0
2

The other answer, suggesting --no-messages/-s, is more appropriate for your problem, but the following will also work for commands that don't have a "silent" option.

Redirecting the command

To redirect errors from a simple command, you should put the redirection with that command, ie. in the same position in the pipeline:

if [ "$(grep -v '^;\|^\[' "path_to_file/config.ini" 2>/dev/null | \
 grep -c '\\some_word')" -ge 1 ] \

The first grep is the one generating the "No such file or directory" message, so that's the one that has to be redirected.

Redirecting the pipeline

If multiple parts of the pipeline can generate errors, you could place the entire pipeline in a group, with a single redirection after it:

if [ "$( ( grep -v '^;\|^\[' "path_to_file/config.ini" | \
 grep -v -f "path_to_file/ignored_patterns" | \
 grep -c '\\some_word' ) 2>/dev/null )" -ge 1 ] \

Redirecting the conditional construct

You can redirect the whole of the if construct by putting the redirection after the closing fi:

if [ "$(grep -v '^;\|^\[' "path_to_file/config.ini" | \
 grep -c '\\some_word')" -ge 1 ] \
 ...
else
 ...
fi 2>/dev/null

This will redirect errors from all commands (both test- and consequent-) inside that block.

answered Jan 31, 2017 at 11:26

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.