finding a specific part of a variable? - bash

Ok I know my question seems confusing. So i'll explain it here. So i'm making a mmo with bash script (i am bored don't say do it with java or c++ or something like that please) which i won't really explain other than that when registering I want it so I can have a if statement see if they have anything provocative in their username and then tell them this and then make them make a different username. I'm just trying to make it more appropriate and all. So to make it so I can have the word seen by my if statement I need to have it like this pretty much
if [ var == provocative word ]; then
echo "You have a provocative word in your username. Please change"
fi
But to do this I'll need it to look if word is in the statement.
I know that in java it is just by doing 'word*' the star making it so if it sees the word it will so whatever the if said even though the thing might of been 'wordghdksjgh'. Thanks in advance for whoever answers.

To check if a variable contains a substring, you can use:
if [[ $var == *"foo"* ]]
then
echo "The variable contains the substring 'foo'"
fi

In addition to pattern-matching using
if [[ $var = *foo* ]]; then
you can also use regular expressions:
if [[ $var =~ foo ]]; then # Successfully match anything with "foo" as a substring
The nocasematch option applies to regular expression matches as well.

Related

bash: comparing strings with grep-variable issue

bash-newbie here.
I want to use the following simple script as a shortcut to enable/disable the touchpad of my laptop:
#!/bin/bash
result=$(xinput --list-props 11 | grep "Device Enabled")
echo $result
# Output: Device Enabled (140): 1
if [[ "$result" = "Device Enabled (140): 1" ]]; then
`xinput set-prop 11 "Device Enabled" 0`
else
`xinput set-prop 11 "Device Enabled" 1`
fi
The if-condition is however never entered. echo $result shows that the variable really contains the string-value that I want to compare. I have been searching for a while but can not at all figure out why the result-variable and the string do not match in the if-condition.
The string obtained by grep has a tab at the beginning, which needed to be included in the compared string. Checking again with echo "$result" (with added quotation marks) helped.
In bash (but not more basic shells), you can use [[ ]]'s pattern matching capabilities to check whether a string contains a pattern; using it this way removes the need to worry about leading tabs, or even the need to use grep to pick out the relevant line:
if [[ "$(xinput --list-props 11 | grep "Device Enabled")" = *"Device Enabled (140): 1"* ]]; then
Note that the *s at the beginning and end of the pattern mean "preceded by anything" and "followed by anything" respectively.
Also, the double-quotes around $(xinput ...) aren't really necessary here, but IMO keeping track of which places are safe to leave double-quotes off and when it's not safe is too much trouble. (The left side of an = comparison inside [[ ]] is one of the safe places, but the right side isn't, and in [ ] it's almost never safe -- good luck remembering all that correctly!) So I prefer to just always use double-quotes.

Ubuntu bash script string contains similar words

I am trying to write a bash script that will tell whether two strings are of similar value. I have produced this bash script:
#!/bin/bash
value="java.lang.NullPointerException"
if [[ "java.lang.NullPointerException" = "$value" || "java.lang.NullPointerException" == "$value"* ]]; then
echo "Match"
fi
Basically what I want to achive, is that if two strings are of equal value or a very similar either side but with matching text in the middle then echo "Match".
I have tried a number of resources but can't get this example to work. I have taken a look at:
In bash, how can I check if a string begins with some value?
How to test that a variable starts with a string in bash?
https://ubuntuforums.org/showthread.php?t=1118003
Please note these values would eventually come from a text file and so the values will be in a form of variables. I have tried different approaches, but don't seem to get it working. I just want to get this if statement working. It works for matching text but not for values either side. Value could be "java.lang.NullPointerException: Unexpected" or "Unexpected java.lang.NullPointerException".
#!/bin/bash
value="java.lang.NullPointerException" #or java.lang.NullPointerException: Unexpected
if [[ $value == *"java.lang.NullPointerException"* ]];
then
echo "Match"
fi
A simple and portable (POSIX compliant) technique for wildcard matching is to use a case statement rather than if. For your example, this would look something like
#!/bin/sh
value="java.lang.NullPointerException"
case "$value" in
*java.lang.NullPointerException*) echo Match;;
esac

BASH if then else with quoted text

I'm trying to write a short script that checks for verizon fios availability by zip code from a list of 5 digit us zip codes.
The basis of this I have working but comparing the recived output from curl to the expected output in the if statements isn't working.
I know there is a better & cleaner way to do this however I'm really interested in what is wrong with this method. I think it's something to do with the quotes getting jumbled up.
Let me know what you guys think. I originally thought this would be a quick little script. ha. Thanks for the help
Here is what I have so far:
#!/bin/bash
Avail='<link rel="canonical" href="http://fios.verizon.com/fios-plans.html#availability-msg" />'
NotAvail='<link rel="canonical" href="http://fios.verizon.com/order-now.html#availability-msg" />'
while read zip; do
chk=`curl -s -d "ref=GIa6uiuwP81j047HjKMHOwEyW4QJTYjG&PageID=page9765&AvailabilityZipCode=$zip" http://fios.verizon.com/availability_post4.php --Location | grep "availability-msg"`
#echo $chk
if [ "$chk" = "$Avail" ]
then
fios=1
elif [ "$chk" = "$NotAvail" ]
then
fios=0
else
fios=err
fi
echo "$zip | $fios"
done < zipcodes.txt
Most likely, the line read from curl ends in CR/LF. grep will take the LF as a line-end, and leave the CR in the line, where it will not match either of your patterns. (Other whitespace issues could also cause a similarly invisible mismatch, but stray CR's are very common since HTTP insists on them.)
The easiest solution is to use a less specific match, like a glob or regex; these are both available with bash's [[ (rather than [) command.
Eg.:
if [[ $chk =~ /fios-plans\.html ]]; then
will do a substring comparison

String contains in Bash that is a directory path

I am writing an SVN script that will export only changed files. In doing so I only want to export the files if they don't contain a specific file.
So, to start out I am modifying the script found here.
I found a way to check if a string contains using the functionality found here.
Now, when I try to run the following:
filename=`echo "$line" |sed "s|$repository||g"`
if [ ! -d $target_directory$filename ] && [[!"$filename" =~ *myfile* ]] ; then
fi
However I keep getting errors stating:
/home/home/myfile: "no such file or directory"
It appears that BASH is treating $filename as a literal. How do I get it so that it reads it as a string and not a path?
Thanks for your help!
You have some syntax issues (a shell script linter can weed those out):
You need a space after "[[", otherwise it'll be interpretted as a command (giving an error similar to what you posted).
You need a space after the "!", otherwise it'll be considered part of the operand.
You also need something in the then clause, but since you managed to run it, I'll assume you just left it out.
You combined two difference answers from the substring thing you posted, [[ $foo == *bar* ]] and [[ $foo =~ .*bar.* ]]. The first uses a glob, the second uses a regex. Just use [[ ! $filename == *myfile* ]]

Check for valid link (URL)

I was reading though this other question which has some really good regex's for the job but as far as I can see non of them work with BASH commands as BASH commands don't support such complex rexeg's.
if echo "http://www.google.com/test/link.php" | grep -q '(https?|ftp|file)://[-A-Z0-9\+&##/%?=~_|!:,.;]*[-A-Z0-9\+&##/%=~_|]'; then
echo "Link valid"
else
echo "Link not valid"
fi
But this doesn't work as grep -q doesn't work ...
Edit, ok I just realised that grep had an "extended-regex" (-E) option which seems to make it work. But if anyone has a better/faster way I would still love to here about it.
The following works in Bash >= version 3.2 without using grep:
regex='(https?|ftp|file)://[-[:alnum:]\+&##/%?=~_|!:,.;]*[-[:alnum:]\+&##/%=~_|]'
string='http://www.google.com/test/link.php'
if [[ $string =~ $regex ]]
then
echo "Link valid"
else
echo "Link not valid"
fi
I simplified your regex by using [:alnum:] which also matches any alphanumeric character (e.g. Э or ß), but support varies by the underlying regex library. This is another potential simplification which uses + instead of * and a repeated sequence (although your second sequence is different from the first).
regex='(https?|ftp|file)://[-[:alnum:]\+&##/%?=~_|!:,.;]+'
Since I don't have enough rep to comment above, I am going to amend the answer given by Dennis above with this one.
I incorporated Christopher's update to the regex and then added more to it so that the URL has to at least be in this format:
http://w.w (has to have a period in it).
And tweaked output a bit :)
regex='^(https?|ftp|file)://[-A-Za-z0-9\+&##/%?=~_|!:,.;]*[-A-Za-z0-9\+&##/%=~_|]\.[-A-Za-z0-9\+&##/%?=~_|!:,.;]*[-A-Za-z0-9\+&##/%=~_|]$'
url='http://www.google.com/test/link.php'
if [[ $url =~ $regex ]]
then
echo "$url IS valid"
else
echo "$url IS NOT valid"
fi
Probably because the regular expression is written in PCRE syntax. See if you have (or can install) the program pcregrep on your system - it has the same syntax as grep but accepts Perl-compatible regexes - and you should be able to make that work.
Another option is to try the -P option to grep, but the man page says that's "highly experimental" so it may or may not actually work.
I will say that you should think carefully about whether it's really appropriate to be using this or any regex to validate a URL. If you want to have a correct validation, you'd probably be better off finding or writing a small script in, say, Perl, to use the URL validation facilities of the language.
EDIT: In response to your edit in the question, I didn't notice that that regex is also valid in "extended" syntax. I don't think you can get better/faster than that.

Resources