I am new to Bash and having a problem checking a variable contains a string
Works:
foo="abc def ghi"
if [[ "$foo" =~ "def" ]]; then
echo "Match!"
fi
Does not work (issue i'm having):
javaVersion="$(java -version)"
if [[ "$javaVersion" =~ "1.8.0_74" ]]; then
echo "Match!"
fi
I have manually checked the variable contains the string 1.8.0_74.
The problem is java -version prints the information to stderr(2) stream instead of stdout(1). You need to capture both of them as 2>&1 which literally means write the standard error output stream also to standard output stream.
javaVersion="$(java -version 2>&1)"
if [[ "$javaVersion" =~ "1.8.0_74" ]]; then
echo "Match!"
fi
will work as expected.
Also you don't a a regex operator for this comparison, a simple glob comparison using the test operator [[ would suffice,
if [[ "$javaVersion" == *"1.8.0_74"* ]]; then
echo "Match!"
fi
Related
I have an array of possible file extensions, which contains some wild cards e.g.:
FILETYPES=("DBG" "MSG" "OUT" "output*.txt")
I also have a list of files, which I am grabbing the file extension from. I then need to compare the extension with the array of file extensions.
I have tried:
if [[ ${EXTENSION} =~ "${FILETYPES[*]}" ]]; then
echo "file found"
fi
if [[ ${EXTENSION} == "${FILETYPES[*]}" ]]; then
echo "file found"
fi
and
if [[ ${EXTENSION} =~ "${FILETYPES[*]}" ]]; then
echo "file found"
fi
But to no avail
I tried:
if [[ "${FILETYPES[*]}" =~ ${EXTENSION} ]]; then
echo "file found"
fi
However, it ended up comparing "txt" to "output*.txt" and concluding it was a match.
FILETYPES=("DBG" "MSG" "OUT" "output*.txt") First of all, avoid ALL_CAPS variable names except if these are meant as global environment variables.
"output*.txt": is ok as a globing pattern, for bash test [[ $variable == output*.txt ]] for example. But for Regex matching it needs a different syntax like [[ $variable =~ output.*\.txt ]]
"${FILETYPES[*]}": Expanding this array into a single_string was mostly a good approach, but it needs clever use of the IFS environment variable to help it expands into a Regex. Something like IFS='|' regex_fragment="(${array[*]})", so that each array entry will be expanded, separated by a pipe | and enclosed in parenthesis as (entry1|entry2|...).
Here is an implementation you could use:
textscript.sh
#!/usr/bin/env bash
extensions_regexes=("DBG" "MSG" "OUT" "output.*\.txt")
# Expands the extensions regexes into a proper regex string
IFS='|' regex=".*\.(${extensions_regexes[*]})"
# Prints the regex for debug purposes
printf %s\\n "$regex"
# Iterate all filenames passed as argument to the script
for filename; do
# Compare the filename with the regex
if [[ $filename =~ $regex ]]; then
printf 'file found: %s \n' "$filename"
fi
done
Sample usage:
$ touch foobar.MSG foobar.output.txt
$ bash testscript.sh *
.*\.(DBG|MSG|OUT|output.*\.txt)
file found: foobar.MSG
file found: foobar.output.txt
You cannot directly compare a string with an array. Would you please try something like:
filetypes=("DBG" "MSG" "OUT" "output*.txt")
extension="MSG" # example
match=0
for type in "${filetypes[#]}"; do
if [[ $extension = $type ]]; then
match=1
break
fi
done
echo "$match"
You can save looping with regex:
pat="^(DBG|MSG|OUT|output.*\.txt)$"
extension="output_foo.txt" # example
match=0
if [[ $extension =~ $pat ]]; then
match=1
fi
echo "$match"
Please note the expressions of regex differ from wildcards for globbing.
As a side note, we conventionally do not use uppercases for user variables to avoid conflicts with system variables.
bash script
Hi! I would like to make a bash script that contolli if the content of a var variable does pattern matching with the string ending with ABC?
You can use the bash builtins:
# with glob patterns
if [[ $var == *ABC ]]; then echo "$var ends with ABC"; fi
# with regular expression
if [[ $var =~ ABC$ ]]; then echo "$var ends with ABC"; fi
You are almost there
var="hellowordABC"
echo $var | grep ".*ABC$"
Or using builtin conditions
[[ $var =~ ABC$ ]] && echo "var ends with ABC"
I am very new to Bash Scripting and I have a question regarding my CheckOurCodingRules.sh script:
I want to search for every 'hPar,' in a textfile and if found it should be checked if there is a also a 'const' in the same row.
Thats what I got so far but there is something wrong here:
while read line
do
if [[ $line == *hPar\,* ]] && [[ $line == *const\*]];then
DOCUMENTATION_TEST_A=1
else
echo DOCUMENTATION_TEST_A=0
fi
done < $INPUT_FILE
if [[DOCUMENTATION_TEST_A=0]];then
echo "error: Rule1: No const before hpar"
fi
There are a couple of issues with your script, see the code below which works for me:
DOCUMENTATION_TEST_A=0 # initial value
while read line
do
# spaces between conditional and brackets, no backslashes
if [[ $line == *hPar,* ]] && [[ $line == *const* ]]
then
DOCUMENTATION_TEST_A=1
break # optional, no need to scan the rest of the file
fi
done < $INPUT_FILE
# spaces and $, -eq is used for numerical comparisons
if [[ $DOCUMENTATION_TEST_A -eq 0 ]];
then
echo "error: Rule1: No const before hpar"
fi
A cleaner solution would be to use grep:
if ! grep "hPar," $INPUT_FILE | grep "const" >/dev/null
then
echo "error: Rule1: No const before hpar"
fi
I have a string ${testmystring} in my .sh script and I want to check if this string does not contain another string.
if [[ ${testmystring} doesNotContain *"c0"* ]];then
# testmystring does not contain c0
fi
How can I do that, i.e. what is doesNotContain supposed to be?
Use !=.
if [[ ${testmystring} != *"c0"* ]];then
# testmystring does not contain c0
fi
See help [[ for more information.
Bash allow u to use =~ to test if the substring is contained.
Ergo, the use of negate will allow to test the opposite.
fullstring="123asdf123"
substringA=asdf
substringB=gdsaf
# test for contains asdf, gdsaf and for NOT CONTAINS gdsaf
[[ $fullstring =~ $substring ]] && echo "found substring $substring in $fullstring"
[[ $fullstring =~ $substringB ]] && echo "found substring $substringB in $fullstring" || echo "failed to find"
[[ ! $fullstring =~ $substringB ]] && echo "did not find substring $substringB in $fullstring"
As mainframer said, you can use grep, but i would use exit status for testing, try this:
#!/bin/bash
# Test if anotherstring is contained in teststring
teststring="put you string here"
anotherstring="string"
echo ${teststring} | grep --quiet "${anotherstring}"
# Exit status 0 means anotherstring was found
# Exit status 1 means anotherstring was not found
if [ $? = 1 ]
then
echo "$anotherstring was not found"
fi
I need help with how to compare bash variable to a specific format.
i will read user input with read command
for example:
MyComputer:~/Home$ read interface
eth1
MyComputer:~/Home$ echo $interface
eth1
Now i need to check if "$interface" variable with IF loop(it should have "eth" in beginning and should contains numbers 0-9):
if [[ $interface=^eth[0-9] ]]
then
echo "It looks like an interface name"
fi
Thanks in advance
You can use regular expressions for this:
if [[ $interface =~ ^eth[0-9]+$ ]]
then
...
fi
You can use bash's globs for this:
if [[ $interface = eth+([[:digit:]]) ]]; then
echo "It looks like an interface name"
fi
(avoiding regexps removes one problem). Oh, and mind the spaces around the = sign, and also before and after [[ and ]].
You could use bash V3+ operator =~ as Andrew Logvinov said :
[[ $interface =~ ^eth[0-9]+$ ]] && # ...
Or :
if [[ $interface =~ ^eth[0-9]+$ ]]; then
# ...
fi
Otherwise, you could use too egrep or grep -E (which is useful with older shells like sh...) :
echo "$interface"|egrep "^eth[0-9]+$" > /dev/null && # ...
Or :
if echo "$interface"|egrep "^eth[0-9]+$" > /dev/null; then
# ...
fi