I want to check if a file contains a specific string or not in bash. I used this script, but it doesn't work:
if [[ 'grep 'SomeString' $File' ]];then
# Some Actions
fi
What's wrong in my code?
if grep -q SomeString "$File"; then
Some Actions # SomeString was found
fi
You don't need [[ ]] here. Just run the command directly. Add -q option when you don't need the string displayed when it was found.
The grep command returns 0 or 1 in the exit code depending on
the result of search. 0 if something was found; 1 otherwise.
$ echo hello | grep hi ; echo $?
1
$ echo hello | grep he ; echo $?
hello
0
$ echo hello | grep -q he ; echo $?
0
You can specify commands as an condition of if. If the command returns 0 in its exitcode that means that the condition is true; otherwise false.
$ if /bin/true; then echo that is true; fi
that is true
$ if /bin/false; then echo that is true; fi
$
As you can see you run here the programs directly. No additional [] or [[]].
In case if you want to check whether file does not contain a specific string, you can do it as follows.
if ! grep -q SomeString "$File"; then
Some Actions # SomeString was not found
fi
In addition to other answers, which told you how to do what you wanted, I try to explain what was wrong (which is what you wanted.
In Bash, if is to be followed with a command. If the exit code of this command is equal to 0, then the then part is executed, else the else part if any is executed.
You can do that with any command as explained in other answers: if /bin/true; then ...; fi
[[ is an internal bash command dedicated to some tests, like file existence, variable comparisons. Similarly [ is an external command (it is located typically in /usr/bin/[) that performs roughly the same tests but needs ] as a final argument, which is why ] must be padded with a space on the left, which is not the case with ]].
Here you needn't [[ nor [.
Another thing is the way you quote things. In bash, there is only one case where pairs of quotes do nest, it is "$(command "argument")". But in 'grep 'SomeString' $File' you have only one word, because 'grep ' is a quoted unit, which is concatenated with SomeString and then again concatenated with ' $File'. The variable $File is not even replaced with its value because of the use of single quotes. The proper way to do that is grep 'SomeString' "$File".
Shortest (correct) version:
grep -q "something" file; [ $? -eq 0 ] && echo "yes" || echo "no"
can be also written as
grep -q "something" file; test $? -eq 0 && echo "yes" || echo "no"
but you dont need to explicitly test it in this case, so the same with:
grep -q "something" file && echo "yes" || echo "no"
##To check for a particular string in a file
cd PATH_TO_YOUR_DIRECTORY #Changing directory to your working directory
File=YOUR_FILENAME
if grep -q STRING_YOU_ARE_CHECKING_FOR "$File"; ##note the space after the string you are searching for
then
echo "Hooray!!It's available"
else
echo "Oops!!Not available"
fi
grep -q [PATTERN] [FILE] && echo $?
The exit status is 0 (true) if the pattern was found; otherwise blankstring.
if grep -q [string] [filename]
then
[whatever action]
fi
Example
if grep -q 'my cat is in a tree' /tmp/cat.txt
then
mkdir cat
fi
In case you want to checkif the string matches the whole line and if it is a fixed string, You can do it this way
grep -Fxq [String] [filePath]
example
searchString="Hello World"
file="./test.log"
if grep -Fxq "$searchString" $file
then
echo "String found in $file"
else
echo "String not found in $file"
fi
From the man file:
-F, --fixed-strings
Interpret PATTERN as a list of fixed strings, separated by newlines, any of
which is to be matched.
(-F is specified by POSIX.)
-x, --line-regexp
Select only those matches that exactly match the whole line. (-x is specified by
POSIX.)
-q, --quiet, --silent
Quiet; do not write anything to standard output. Exit immediately with zero
status if any match is
found, even if an error was detected. Also see the -s or --no-messages
option. (-q is specified by
POSIX.)
Try this:
if [[ $(grep "SomeString" $File) ]] ; then
echo "Found"
else
echo "Not Found"
fi
I done this, seems to work fine
if grep $SearchTerm $FileToSearch; then
echo "$SearchTerm found OK"
else
echo "$SearchTerm not found"
fi
grep -q "something" file
[[ !? -eq 0 ]] && echo "yes" || echo "no"
I'm trying to learn the bash language. How do I execute a Linux command with a dynamic argument and check whether or not the returning string is empty. For example:
if ls "my_directory123" == `emtpy string` then
....
end
If you are testing for an empty directory pass in the first positional parameter "$1", you can test:
if test -z "$(ls -A "$1")" ; then
or
if [ -z "$(ls -A "$1")" ]; then
which are equivalent uses of the test of [ keywords.
Assign the result of the command to a variable and compare it as a string.
result=$(ls "my_directory123")
if [ "$result" = "" ]
then
echo empty
fi
TEST=`ls`
if [$TEST == ""]; then
echo "do something"
fi
if you want to run this in the terminal you key in each line at a time. If you prefer you can put everything in a file prepend with
#!/bin/bash
to make an executable string once you run
chmod +x FILENAME
Need to call Command Substitution and check for returned value. Some think like this
x=$(ls path)
if [ -z "$x" ] ;then echo empty ; else echo no empty; fi
I wanted to see if there is a parameter provided. But i don't know why this code wont work. What am i doing wrong?
if ![ -z "$1" ]
then
echo "$1"
fi
Let's ask shellcheck:
In file line 1:
if ![ -z "$1" ]
^-- SC1035: You need a space here.
In other words:
if ! [ -z "$1" ]
then
echo "$1"
fi
If, as per your comment, it still doesn't work and you happen to be doing this from a function, the function's parameters will mask the script's parameters, and we have to pass them explicitly:
In file line 8:
call_it
^-- SC2119: Use call_it "$#" if function's $1 should mean script's $1.
You could check the number of given parameters. $# represents the number of parameters - or the length of the array containing the parameters - passed to a script or a function. If it is zero then no parameters have been passed. Here is a good read about positional parameters in general.
$ cat script
#!/usr/bin/env bash
if (( $# == 0 )); then
echo "No parameters provided"
else
echo "Number of parameters is $#"
fi
Result:
$ ./script
No parameters provided
$ ./script first
Number of parameters is 1
$ ./script first second
Number of parameters is 2
If you would like to check the parameters passed to the script with a function then you would have to provide the script parameters to the function:
$ cat script
#!/usr/bin/env bash
_checkParameters()
{
if (( $1 == 0 )); then
echo "No parameters provided"
else
echo "Number of parameters is $1"
fi
}
_checkParameters $#
This will return the same results as in the first example.
Also related: What are the special dollar sign shell variables?
I want in a bash script (Linux) to check, if two files are identical.
I use the following code:
#!/bin/bash
…
…
differ=$(diff $FILENAME.out_ok $FILENAME.out)
echo "******************"
echo $differ
echo "******************"
if [ $differ=="" ]
then
echo "pass"
else
echo "Error ! different output"
echo $differ
fi
The problem:
the diff command return white space and break the if command
output
******************
82c82 < ---------------------- --- > ---------------------
******************
./test.sh: line 32: [: too many arguments
Error ! different output
The correct tool for checking whether two files are identical is cmp.
if cmp -s $FILENAME.out_ok $FILENAME.out
then : They are the same
else : They are different
fi
Or, in this context:
if cmp -s $FILENAME.out_ok $FILENAME.out
then
echo "pass"
else
echo "Error ! different output"
diff $FILENAME.out_ok $FILENAME.out
fi
If you want to use the diff program, then double quote your variable (and use spaces around the arguments to the [ command):
if [ -z "$differ" ]
then
echo "pass"
else
echo "Error ! different output"
echo "$differ"
fi
Note that you need to double quote the variable when you echo it to ensure that newlines etc are preserved in the output; if you don't, everything is mushed onto a single line.
Or use the [[ test:
if [[ "$differ" == "" ]]
then
echo "pass"
else
echo "Error ! different output"
echo "$differ"
fi
Here, the quotes are not strictly necessary around the variable in the condition, but old school shell scripters like me would put them there automatically and harmlessly. Roughly, if the variable might contain spaces and the spaces matter, it should be double quoted. I don't see a need to learn a special case for the [[ command when it works fine with double quotes too.
Instead of:
if [ $differ=="" ]
Use:
if [[ $differ == "" ]]
Better to use modern [[ and ]] instead of an external program /bin/[
Also use diff -b to compare 2 files while ignoring white spaces
#anubhava answer is correct,
you can also use
if [ "$differ" == "" ]
I pass a string as an argument to a shell script. and the shell script should tell me if the passed argument is a variable
something like this
if [ ! -z ${$1} ] ; then
echo yes! $1 is a variable and its value is ${$1}
fi
but this gives me bad substitution err..
I definitely know i'm missing something.. help me out!
Eg usage:
$ myscript.sh HOME
yes! HOME is a variable and its value is /home/raj
The syntax for this is:
${!VAR}
Example:
$ function hello() { echo ${!1}; }
$ hello HOME
/home/me
Found it here:
http://www.linuxquestions.org/questions/programming-9/bash-how-to-get-variable-name-from-variable-274718/
All you should do:
if [ ! -z ${!1} ]; then
echo yes $1 is a variable and its value is ${!1}
fi