Running command uname -r gives us:
3.10.0-229.14.1.el7.x86_64
I need to extract "el7". I'm not that great with regexp and could use a helping hand. If you could, explain what is going on in the solution.
Thank you
In BASH you can use this regex:
s='3.10.0-229.14.1.el7.x86_64'
[[ $s =~ ([^.]+)\.[^.]+$ ]] && echo "${BASH_REMATCH[1]}"
el7
Or without regex using awk:
uname -r | awk -F '.' '{print $(NF-1)}'
el7
Related
I am able to validate IPv6 addresses using java with following regex:
([0-9a-fA-F]{0,4}:){1,7}([0-9a-fA-F]){0,4}
But I need to do this in shell script to which I am new.
This regex doesn't seem to work in shell. Have tried some other combinations also but nothing helped.
#!/bin/bash
regex="([0-9a-fA-F]{0,4}:){1,7}([0-9a-fA-F]){0,4}"
var="$1"
if [[ "$var" =~ "$regex" ]]
then
echo "matches"
else
echo "doesn't match!"
fi
It gives output doesn't match! for 2001:0Db8:85a3:0000:0000:8a2e:0370:7334
How can I write this in shell script?
Java regex shown in question would work in bash as well but make sure to not to use quoted regex variable. If the variable or string on the right hand side of =~ operator is quoted, then it is treated as a string literal instead of regex.
I also recommend using anchors in regex. Otherwise it will print matches for invalid input as: 2001:0db8:85a3:0000:0000:8a2e:0370:7334:foo:bar:baz.
Following script should work for you:
#!/bin/bash
regex='^([0-9a-fA-F]{0,4}:){1,7}[0-9a-fA-F]{0,4}$'
var="$1"
if [[ $var =~ $regex ]]; then
echo "matches"
else
echo "doesn't match!"
fi
[[ and =~ won't work with sh, and awk almost works everywhere.
Here is what I did
saved as ./check-ipv6.sh, chmod +x ./check-ipv6.sh
#!/bin/sh
regex='^([0-9a-fA-F]{0,4}:){1,7}[0-9a-fA-F]{0,4}$'
echo -n "$1" | awk '$0 !~ /'"$regex"'/{print "not an ipv6=>"$0;exit 1}'
Or you prefer bash than sh
#!/bin/bash
regex='^([0-9a-fA-F]{0,4}:){1,7}[0-9a-fA-F]{0,4}$'
awk '$0 !~ /'"$regex"'/{print "not an ipv6=>"$0;exit 1}' <<< "$1"
Test
~$ ./check-ipv6.sh 2001:0Db8:85a3:0000:0000:8a2e:0370:7334x
not an ipv6=>2001:0Db8:85a3:0000:0000:8a2e:0370:7334x
~$ echo $?
1
~$ ./check-ipv6.sh 2001:0Db8:85a3:0000:0000:8a2e:0370:7334
~$ echo $?
0
I have a string something like this
xsd:import schemaLocation="AppointmentManagementService.xsd6.xsd" namespace=
I want to extract the following from it :
AppointmentManagementService.xsd6.xsd
I have tried using regex, bash and sed with no success. Can someone please help me out with this?
The regex that I used was this :
/AppointmentManagementService.xsd\d{1,2}.xsd/g
Your string is:
nampt#nampt-desktop:$ cat 1
xsd:import schemaLocation="AppointmentManagementService.xsd6.xsd" namespace=
Try with awk:
cat 1 | awk -F "\"" '{print $2}'
Output:
AppointmentManagementService.xsd6.xsd
sed doesn't recognize \d, use [0-9] or [[:digit:]] instead:
sed 's/^.*schemaLocation="\([^"]\+[[:digit:]]\{1,2\}\.xsd\)".*$/\1/g'
## or
sed 's/^.*schemaLocation="\([^"]\+[0-9]\{1,2\}\.xsd\)".*$/\1/g'
You can use bash native regex matching:
$ in='xsd:import schemaLocation="AppointmentManagementService.xsd6.xsd" namespace='
$ if [[ $in =~ \"(.+)\" ]]; then echo "${BASH_REMATCH[1]}"; fi
Output:
AppointmentManagementService.xsd6.xsd
Based on your example, if you want to grant, at least, 1 or, at most, 2 digits in the .xsd... component, you can fine tune the regex with:
$ if [[ $in =~ \"(AppointmentManagementService.xsd[0-9]{1,2}.xsd)\" ]]; then echo "${BASH_REMATCH[1]}"; fi
using PCRE in GNU grep
grep -oP 'schemaLocation="\K.*?(?=")'
this will output pattern matched between schemaLocation=" and very next occurrence of "
Reference:
https://unix.stackexchange.com/a/13472/109046
Also we can use 'cut' command for this purpose,
[root#code]# echo "xsd:import schemaLocation=\"AppointmentManagementService.xsd6.xsd\" namespace=" | cut -d\" -f 2
AppointmentManagementService.xsd6.xsd
s='xsd:import schemaLocation="AppointmentManagementService.xsd6.xsd" namespace='
echo $s | sed 's/.*schemaLocation="\(.*\)" namespace=.*/\1/'
I want a pair of numbers after a pattern in a line, the pattern is 'mt=' and its position is variable in the line, so if I have mt=83, I only want 83.
I have the next code with an example of the line:
LINE=(10)un=5518666915/(34)ni=vvaummas03.me/ty=12/it=4/et=13/(8)id=ead57a5c/pt=7/to=20130408T155959Z/ot=2/(15)ed=ChangedGreeting/(16)ms=session_11218671/mt=81/
echo "$(expr substr $LINE $(($(echo $LINE | grep -b -o 'mt=' | cut -d: -f1)+4)) 2)"
I know the instruction can be improved, but it worked for me in CentOS, Cygwin and OpenSUSE, but when I run it in Solaris, the terminal show me that grep option -o and the -f1 instruction are invalid. I'm also having trouble with the instruction awk and another options like -c with cut; its very limited so I am searching for common commands on Solaris. I am not allowed to change or install anything on the system.
Any suggestions?
Since you have only a limited set of options it would be possible to do this using only Bash 3 or newer versions with regex matching:
if [[ "$LINE" =~ ^.*mt=([0-9]+).*$ ]]; then
printf "%s\n" "${BASH_REMATCH[1]}"
fi
This will capture any number with a least one digit, following the pattern mt= in the string.
How about this:
~]$ LINE="(10)un=5518666915/(34)ni=vvaummas03.me/ty=12/it=4/et=13/(8)id=ead57a5c/pt=7/to=20130408T155959Z/ot=2/(15)ed=ChangedGreeting/(16)ms=session_11218671/mt=81/"
~]$ echo $LINE | sed -e "s/.*mt=\([0-9]\+\).*/\1/"
81
I have a path such as thus ..
/Users/me/bla/dev/trunk/source/java/com/mecorp/sub/misc/filename.java
I'd like to be able to use bash to create the package structure in another dir somewhere e.g.
com/mecorp/sub/misc/
I tried the following but it wont work .. I was able to get a match if I change my regex to .* so that implies my bash is ok - There must be something wrong with the way im quoting the regex or maybe the regex its self. I do see working here ..
http://regexr.com?3439m
So im confused ?
regex="(?<=/java)(.*)(?=/)"
[[ $fullfile =~ $regex ]]
echo "pkg name " ${BASH_REMATCH[0]}
Thanks for your time.
EDIT - I'm using OSX so it doesn't have all those nice spiffy GNU extensions.
Try this :
using GNU grep :
$ echo '/Users/me/bla/dev/trunk/source/java/com/mecorp/sub/misc/filename.java' |
grep -oP 'java/\K.*/'
com/mecorp/sub/misc/
See http://regexr.com?3439p
Or using bash :
x="/Users/me/bla/dev/trunk/source/java/com/mecorp/sub/misc/filename.java"
[[ $x =~ java/(.*/) ]] && echo ${BASH_REMATCH[1]}
Or with awk :
echo "$x" | awk -F/ '{print gensub(".*/java/(.*/).*", "\\1", $0)}'
Or with sed :
echo "$x" | sed -e 's#.*/java/\(.*/\).*#\1#'
If you try to extract the path after /java/ you can do it with this:
path=/Users/me/bla/dev/trunk/source/java/com/mecorp/sub/misc/filename.java
package=`echo $path | sed -r 's,^.*/java/(.*/).*$,\1,'`
I am using Ubuntu 10.10 and using Grep to process some HTML files.
Here is the HTML snippet:
<a href="video.php?video=one-hd.mov"><img src="/1.jpg"><a href="video.php?video=normal.mov"><img src="/2.jpg"><a href="video.php?video=another-hd.mov">
I would like to extract one-hd.mov and another-hd.mov but ignore normal.mov.
Here is my code:
example='<a href="video.php?video=one-hd.mov"><img src="/1.jpg"><a href="video.php?video=normal.mov"><img src="/2.jpg"><a href="video.php?video=another-hd.mov">'
echo $example | grep -Po '(?<=video.php\?video=).*?(?=-hd.mov">)'
The result is:
one
normal.mov"><img src="/2.jpg"><a href="video.php?video=another
But I want
one
another
There is a mismatch there.
Is this because of the so-called Greedy Regular Expression?
I am sing GREP but any command line bash tools are welcome to solve this problem like sed etc.
Thanks a lot.
You want use Perl regexes for grep - why not directly perl?
echo "$example" | perl -nle 'm/.*?video.php\?video=([^"]+)">.*video.php\?video=([^"]+)".*/; print "=$1=$2="'
will print
=one-hd.mov=another-hd.mov=
Here is a solution using xmlstarlet:
$ example='<a href="video.php?video=one-hd.mov"><img src="/1.jpg"><a href="video.php?video=normal.mov"><img src="/2.jpg"><a href="video.php?video=another-hd.mov">'
$ echo $example | xmlstarlet fo -R 2>/dev/null | xmlstarlet sel -t -m "//*[substring(#href, string-length(#href) - 6, 7) = '-hd.mov']" -v 'substring(#href,17, string-length(#href) - 17 - 3)' -n
one-hd
another-hd
$
Solution using awk:
{
for(i=1;i<NF;i++) {
if ($i ~ /mov/) {
if ($i !~ /normal/){
sub(/^.*=/, "", $i)
print $i
}
}
}
}
outputs:
$ awk -F'"' -f h.awk html
one-hd.mov
another-hd.mov
But I strongly advice you to use a html-parser for this instead, something like BeautifulSoup