SED replace in bash between round brackets - bash

I want to use sed to check if some string match to a pattern and then save that match into a variable:
function tst2(){
string='cms(1.2;1.5;1.3)'
regex='cms\(.*\)'
echo -e $string
if [[ $string =~ $regex ]]
then
myVar=$(echo -e $string | sed "s/cms\(.*\)/\1/g")
echo $myVar
else
echo "too badd!!!"
fi
}
Console output:
[user#home~]$ tst2
cms(1.2;1.5;1.3)
(1.2;1.5;1.3)
I would like myVar to become "1.2;1.5;1.3" (without the round brackets)

This is a faster way without having to use sed. It uses the bash builtin BASH_REMATCH variable filled when the =~ operator is used:
function tst2(){
string='cms(1.2;1.5;1.3)'
regex='cms\((.*)\)'
echo -e $string
if [[ $string =~ $regex ]]
then
echo ${BASH_REMATCH[1]}
else
echo "too badd!!!"
fi
}

myVar=$(expr $string : $regex)
This will do what you want (using the shell's builtin expr). You need to adjust your regex though, to:
regex='cms(\(.*\))'
That matches the brackets yet doesn't include them in the result.

Related

How can I check if a variable is contains only letters

I tried to check the following case:
#!/bin/bash
line="abc"
if [[ "${line}" != [a-z] ]]; then
echo INVALID
fi
And I get INVALID as output. But why?
It's no check if $line contains only a characters in the range [a-z] ?
Use the regular expression matching operator =~:
#!/bin/bash
line="abc"
if [[ "${line}" =~ [^a-zA-Z] ]]; then
echo INVALID
fi
Works in any Bourne shell and wastes no pipes/forks:
case $var in
("") echo "empty";;
(*[!a-z]*) echo "contains a non-alphabetic";;
(*) echo "just alphabetics";;
esac
Use [!a-zA-Z] if you want to allow upper case as well.
Could you please try following and let me know if this helps you.
line="abc"
if echo "$line" | grep -i -q '^[a-z]*$'
then
echo "MATCHED."
else
echo "NOT-MATCHED."
fi
Pattern matches are anchored to the beginning and end of the string, so your code checks if $line is not a single lowercase character. You want to match an arbitrary sequence of lowercase characters, which you can do using extended patterns:
if [[ $line != #([a-z]) ]]; then
or using the regular-expression operator:
if ! [[ $line =~ ^[a-z]+$ ]]; then # there is no negative regex operator like Perl's !~
Why? Because != means "not equal", thats why. You tell bash to compare abc with [a-z]. They are not equal.
Try echo $line | grep -i -q -x '[a-z]*'.
The flag -i makes grep case insensitive.
The flag -x means match the whole line.
The flag -q means print nothing to stdout, just return 1 or 0.

Patter matching variable and string

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"

Pattern matching in shell - not full exact pattern

How to do pattern match in shell
if ( $var ~= /abc/)
As we do like the above command in perl.
Using bash :
if [[ $var =~ regex ]]; then ...; fi
or
if [[ $var == *string* ]]; then ...; fi
or if not using bash :
if echo "$var" | grep &>/dev/null regex; then ...; fi
See
http://wiki.bash-hackers.org/syntax/ccmd/conditional_expression
http://mywiki.wooledge.org/BashGuide/Patterns

Matching one of several possible characters in a string

In a bash (version 3.2.48) script I get a string that can be something like:
'XY'
' Y'
'YY'
etc
So, I have either an alphabetic character OR a space (first slot), then the relevant character (second slot). I tried some variation (without grep, sed, ...) like:
if [[ $string =~ ([[:space]]{1}|[[:alpha:]]{1})M ]]; then
and
if [[ $string =~ (\s{1}|.{1})M ]]; then
but my solutions did not always work correctly (matching correctly every combination).
This should work for you:
if [[ $string =~ [[:space:][:alpha:]]M ]]; then
if [[ ${string:1:1} == "M" ]]; then
echo Heureka
fi
or (if you want to do it with patterns)
if [[ $string =~ ([[:space:]]|[[:alpha:]])M ]]; then
echo Heureka
fi
or (even simpler)
if [[ $string == ?M ]]; then
echo Heureka
fi
Without using regular expressions, simply pattern matching is sufficient:
if [[ $string == [[::upper:]\ ]M ]]; then
echo match
fi
Given your example, you want [[:upper:]] rather than merely [[:alpha:]]

ksh + smart test line solution

I
write the following syntax (part of my ksh script)
to check if the first word of LINE=star
and the second word is car
[[ ` echo $LINE | awk '{print $1}' ` = star ]] && [[ ` echo $LINE | awk '{print $2}' ` = car ]] && print "match"
I need other simple smart and shorter solution then my syntax.
from awk,perl or sed(if it possible to use echo only once or better if we cant not use echo, because I need to save time to minimum)
can I get some ideas?
you don't actually need to call any external tools
set -f
set -- $LINE
case "$1 $2" in
"star car")
echo "match";;
esac
You don't need an external process at all:
[[ $LINE == *([ ])star+([ ])car?([ ]*) ]]
If you also need to extract the first word sometimes (warning, typed directly into the browser):
LINE=${LINE##+[ ]} # strip leading spaces
first_word=${LINE%%[ ]*}
if [[ $LINE = *[ ]* ]]; then
LINE_minus_first_word=${LINE##*+([ ])}
else
LINE_minus_first_word=''
fi
Add a tab inside the brackets if they may appear in $LINE.
set -o noglob
words=($LINE)
[[ "${words[0]} ${words[1]}" == "star car" ]] && print "match"
Edit:
Using ksh and Bash's regex matching (Bash >= version 3.2):
pattern='^[[:blank:]]*star[[:blank:]]+car([[:blank:]]+|$)'
[[ $LINE =~ $pattern ]] && print "match"
You can do:
[[ ` echo $LINE | awk '{printf("%s:%s",$1,$2)}'` = star:car ]] && print "match"

Resources