Can anyone help me understand why this doesn't work? Just trying out some simple regex in bash.
#!/bin/bash
re="-regex_"
if [[ "$re" =~ ^[-[:alpha:]_]+$ ]]; then
echo "Regex"
else
echo "this is not regex"
fi
Cheers
I am assuming that you are hoping that the "-regex_" will evaluate to true in your if statement.
on the [:alpha:] tag there is nothing to say search for more than one alpha-numeric character.
try
[[ "$re" =~ ^-[[:alpha:]]+_$ ]]
If you are having an error running it, make sure you are using unix line endings (run it through dos2unix) and make sure it is marked executable. Otherwise, the script prints "Regex" for me.
Related
So I created myself a cute little bash script:
#!/usr/bin/env bash
TEXT="FOO BAR"
REGEX="FOO (.+)"
if [[ $TEXT =~ $REGEX ]]; then
echo "Matched ${BASH_REMATCH[1]}"
else
echo "No match."
fi
Pretty basic. If I run ./cutescript.sh, then I get the result:
Matched BAR
But if I source the script, . ./cutescript.sh, then it still matches, but BASH_REMATCH[1 is empty.
Wat.
I'm on MacOS Catalina 10.15.7 (19H2), executing this in zsh, but with the bash shebang.
Can anyone explain this irregularity?
When you read the file with ., it gets executed by whatever shell you're running - in this case, you said you're in zsh. The name of the BASH_REMATCH array is, as the name implies, specific to bash; if your shell is zsh, for example, then the matched text in this case would be found in $match[1] instead. And I don't think ksh does true regex matching at all.
Now, armed with the knowledge that BASH_REMATCH doesn't exist natively in zsh, I did a little more digging:
This post is actually a duplicate. There's another question here that explains the solution: BASH_REMATCH doesn't capture
Setting options KSH_ARRAYS BASH_REMATCH allows zsh to emulate bash's regular expression features.
A simple way to make the above script compatible with zsh is:
#!/usr/bin/env bash
# Ensures that BASH_REMATCH works if called in zsh.
setopt KSH_ARRAYS BASH_REMATCH
TEXT="FOO BAR"
REGEX="FOO (.+)"
if [[ $TEXT =~ $REGEX ]]; then
echo "Matched ${BASH_REMATCH[1]}"
else
echo "No match."
fi
unsetopt KSH_ARRAYS BASH_REMATCH
Also another related question: What is the zsh equivalent for $BASH_REMATCH[]?
I'm trying to work out a loop that will let me ignore some matches. So far I have:
for d in /home/chambres/web/x.org/public_html/2018/js/lib/*.js ; do
if [[ $d =~ /*.min.js/ ]];
then
echo "ignore $d"
else
filename="${d##*/}"
echo "$d"
#echo "$filename"
fi
done
However when I run it, they still seem to get included. What am I doing wrong?
/home/chambres/web/x.org/public_html/2018/js/lib/underscore.js.min.js
/home/chambres/web/x.org/public_html/2018/js/lib/tiny-slider.js
/home/chambres/web/x.org/public_html/2018/js/lib/tiny-slider.js.min.js
/home/chambres/web/x.org/public_html/2018/js/lib/underscore.js
BTW I'm a bit of a newbie with bash, so please be kind ;)
In Bash, regular expressions are not enclosed in /, so you should change your test to:
if [[ $d =~ \.min\.js$ ]]
As well as removing the enclosing /, I have escaped the . (otherwise they would match any character) and added a $ to match the end of the string.
But in fact you can use a simpler (and marginally faster) glob match in this case:
if [[ $d = *.min.js ]]
This matches any string that ends in .min.js.
I have a CSV being read into a script that has the phrases:
This port supports SSLv3/TLSv1.0.
This port supports TLSv1.0/TLSv1.1/TLSv1.2.
This port supports TLSv1.2.
What I'm looking to do is setup a REGEX variable on the word/number: TLSv1.0
Then reference that variable in an IF/Then statement. The problem I'm
having is getting the regex to see the TLSv1.0. Could somebody help me
craft my BASH script to see TLSv1.0 when it's along a line that starts off with "This port supports"?
#!/bin/sh
REGEX="\TLSv1.0\"
cat filename.csv | awk -F"," '{gsub(/\"/,"",$4);print $5}' | sed s/\"//g |
while IFS=" " read pluginoutput
do
if [[ "$pluginoutput" =~ $REGEX ]]; then
.
. rest of my code
.
You can see that I'm trying to set the regex in the variable, but it just isn't working. Obviously a typo or something. Does anybody have a regex suggestion?
Thanks,
There are a lot of things wrong here. To pick some key ones:
#!/bin/sh specifies that you want your script to be interpreted with a POSIX-compliant interpreter, but doesn't specify which one. Many of these, like ash or dash, don't have [[ ]], =~, or other extensions which your code depends on. Use #!/bin/bash instead.
In REGEX="\TLSv1.0\", the "s are data, not syntax. This means that they're part of the content being searched for when you do [[ $string =~ $regex ]]. By contrast, regex=TLSv1.0, regex="TLSv1.0" or regex='TLSv1.0' will all have the identical effect, of assigning TLSv1.0 as the content of the regex variable.
That said, as a point on regex syntax, you probably want regex='TLSv1[.]0' -- that way it will only match a ., as opposed to treating the dot as a match-any-character wildcard (as it is in regular-expression syntax).
Personally, I might do something more like the following (if I had a reason to do the parsing in bash rather than to let a single egrep call process all your input):
#!/bin/bash
regex='(^|,)"?This port supports .*TLSv1[.]0.*[.]"?($|,)'
while IFS= read -r line; do
[[ $line =~ $regex ]] && echo "Found TLSv1.0 support"
done
My file names are like this F1616L_GATCAG_L002_R2_001, and I want to extract the name before the first underscore _, in this case, F1616L.
I am a newbie to shell script regex, could someone help with this?
I appreciate it.
You can do that using BASH string manipulation:
s='F1616L_GATCAG_L002_R2_001'
echo "${s%%_*}"
F1616L
UPDATE: To get 2nd part after _:
[[ "$s" =~ ^[^_]+_([^_]+) ]] && echo ${BASH_REMATCH[1]}
GATCAG
my programs starts some services and store its output in tmp variable and I want to match the variable's content if it starts with FATAL keyword or not? and if it contains I will print Port in use using echo command
For example if tmp contains FATAL: Exception in startup, exiting.
I can do it by sed: echo $tmp | sed 's/^FATAL.*/"Port in use"/'
but I want to use the builtin if to match the pattern.
How can I use the shell built in features to match REGEX?
POSIX shell doesn't have a regular expression operator for UNIX ERE or PCRE. But it does have the case keyword:
case "$tmp" in
FATAL*) doSomethingDrastic;;
*) doSomethingNormal;;
esac
You didn't tag the question bash, but if you do have that shell you can do some other kinds of pattern matching or even ERE:
if [[ "$tmp" = FATAL* ]]; then
…
fi
or
if [[ $tmp =~ ^FATAL ]]; then
…
fi
if [ -z "${tmp%FATAL*}" ]
then echo "Start with"
else
echo "Does not start with"
fi
work on KSH, BASH under AIX. Think it's also ok under Linux.
It's not a real regex but the limited regex used for file matching (internal to the shell, not like sed/grep/... that have their own version inside) of the shell. So * and ? could be used