How to get bash ssh version number only? - bash

Running ssh -V gives me:
OpenSSH_7.6p1, OpenSSL 1.1.0i-fips 14 Aug 2018
Now I would like to get just
7.6
to allow me to compare version numbers.
NOTE: I needed the ssh version number to allow me to compare it in my bash scripts. Since I didn't find an easy solution online, I thought it would be nice to document this for future users as a self-answered Q&A.

Could you please try following(tested in GNU awk).
ssh -V 2>&1 | awk -F'[_,]' '{print $2+0}'
where $2+0 means it will look for maximum match of digits only and remove text after it. Which will provide exact version of ssh.

You may use awk also:
ssh -V 2>&1 | awk -F '[^0-9.]+' '{print $2}'
7.6

Using sed:
ssh -V 2>&1 | sed 's/OpenSSH_\([^p]*\)p.*/\1/'
explanation:
2>&1 : for some strange reason ssh prints the version info to stderr; we redirect to stdout to allow parsing.
\([^p]*\) : take all characters that are not a p.

Or with pure Bash Regex:
[[ $(ssh -V 2>&1) =~ [0-9.]+ ]];echo $BASH_REMATCH

Related

egrep gives me what I want, grep -E does not

I have read that egrep is deprecated in favour of grep -E so I'm looking back at my code and changing it where I find it.
But I see that the results are not always as expected.
With egrep, I get my list of running Oracle instances:
ps -ef|grep [p]mon|awk -F'ora_pmon_' '{print $NF}'|egrep -v 'ASM|^$'
halana
bila
halsasa
loana
However with grep -E, I get part of the awk in the results:
ps -ef|grep [p]mon|awk -F'ora_pmon_' '{print $NF}'|grep -Ev 'ASM|^$'
halana
bila
halsasa
{print $NF}
loana
Excluding 'print' obviously works but is it the right way to go about it?:
ps -ef|grep [p]mon|awk -F'ora_pmon_' '{print $NF}'|grep -Ev 'ASM\|^$|print'
halana
bila
halsasa
loana
Is this effect due to the fact that grep -E allows additional regular expression syntax?
Suggesting to simplify your line, eliminate all grep commands:
pgrep -af 'pmon'|awk -F'ora_pmon_' '!/ASM|^$/{print $NF}'
Fold first grep command into pgrep command.
Fold second grep command into awk scirpt !/ASM|^$/{print $NF}
About grep -E vs egrep
There is no difference whatsoever between these commands (they're even provided by the same executable on most operating systems); your old code was vulnerable to this bug too, and if you didn't see it, that's just a matter of being "lucky" in ps getting enough of the process list read before the shell gets to setting up the awk part of the pipeline.
Solving Your Problem
The right answer is already given by #DudiBoy, but the answer with the smallest possible change would be to make your awk (assuming it has GNU extensions and accepts regexes in the field separator specification) escape the string pmon the same way your first grep command does:
ps -ef|grep '[p]mon'|awk -F'ora_[p]mon_' '{print $NF}'|grep -Ev 'ASM|^$'

How can I capture all numbers in a string using sed

I tried to use sed to capture numbers in a string with following script:
echo '["770001,德邦优化混合","750005,安信平稳增长混合发起A"]' | sed -n 's/.*"\(\d{6}\),/\1/p'
My expectation is echo
770001
750005
While nothing output. Why?
In case you are ok with awk then following awk may help you in same. Since I have old version of awk so I am using --re-interval if you have newer version of awk then you may not need it.
echo '["770001,德邦优化混合","750005,安信平稳增长混合发起A"]' |
awk --re-interval '{while(match($0,/[0-9]{6}/)){print substr($0,RSTART,RLENGTH);$0=substr($0,RSTART+RLENGTH+1)}}'
Output will be as follows.
770001
750005

Retrieve bash version in AIX

After the shellshock issue detected on Unix systems with bash, I have to create a script as part of my internship in a firm in order to update bash.
Prerequisites to the installation of the updated IBM bash*.rpm are:
having bash installed (simple check)
having bash version under 4.2.50
I have a problem dealing with the second part, since the true bash version is given by command bash -version instead of rpm -qi bash which essentially gives the version/release of the installation package (and not neccessarily the true bash version).
Basically, my script goes like this:
if [[ bash installed ]] ; then
if [[ bash version installed is < 4.2.50 ]] ; then
install bash version 4.2.50
fi
fi
bash -version returns a lot of text, and I would like to pick out the bash version.
So far, I've used the following command:
$ bash -version | grep version | awk '{print $4}' | head -n 1
That returns :
4.2.50(1)-release
Is there any way to retrieve the real bash version? I've played around with the sed command with no success.
Seems like you're trying to get output like this,
$ bash -version | awk -F'[ (]' '/version/{print $4;exit}'
4.3.11
I guess you can directly use the $BASH_VERSION variable:
$ echo "$BASH_VERSION"
4.2.47(1)-release
From man bash:
Shell Variables
BASH_VERSION
Expands to a string describing the version of this instance of bash.
Then, to check if the version is under or above 4.2.50 you can make use of sort -V to order them:
$ printf "%s\n%s\n" 4.2.50 $BASH_VERSION | sort -V
4.2.47(1)-release
4.2.50
$ printf "%s\n%s\n" 4.2.50 5.2.33 | sort -V
4.2.50
5.2.33
This should be enough for you to determine if your current bash version is under or above the desired one, just some head and tail is needed for the final result.
From man sort:
-V, --version-sort
natural sort of (version) numbers within text

How can I read a file and display only the relevant lines using grep? [duplicate]

This question already has answers here:
grep egrep multiple-strings
(4 answers)
Closed 8 years ago.
I'm trying to read /var/log/messages in order to identify a problem with the pacemakerd.
The problem is that the log is full with notifications from xinetd and nrpe, so the only way i know is:
# tail -n 2000 /var/log/messages |grep -v xinetd | grep -v nrpe |less
So my question is if there's a way to use the -v xinetd and nrpe in the same grep?
Thanks in advance
You can use
grep -v "xinetd\|nrpe"
Sure, you can use first_pattern|second_pattern together with the -E option of grep:
tail -n 2000 /var/log/messages | grep -Ev "xinetd|nrpe"
From man grep:
-E, --extended-regexp
Interpret PATTERN as an extended regular expression (ERE, see below).
(-E is specified by POSIX.)
Example
$ cat a
hello this is me
bye this is me
and that's all
$ grep -Ev "hello|bye" a
and that's all
grep -v "xinetd\|nrpe"
is correct and sufficient. Options like -E or egrep are not necessary.
More variaties:
grep -v "^xinetd\|nrpe" # exclude lines starting with xinetd, and any nrpe"
grep -v "xinetd$\|nrpe" # exclude lines ending with xinetd, and any nrpe"

shell command to truncate/cut a part of string

I have a file with the below contents. I got the command to print version number out of it. But I need to truncate the last part in the version file
file.spec:
Version: 3.12.0.2
Command used:
VERSION=($(grep -r "Version:" /path/file.spec | awk '{print ($2)}'))
echo $VERSION
Current output : 3.12.0.2
Desired output : 3.12.0
There is absolutey no need for external tools like awk, sed etc. for this simple task if your shell is POSIX-compliant (which it should be) and supports parameter expansion:
$ cat file.spec
Version: 3.12.0.2
$ version=$(<file.spec)
$ version="${version#* }"
$ version="${version%.*}"
$ echo "${version}"
3.12.0
Try this:
VERSION=($(grep -r "Version:" /path/file.spec| awk '{print ($2)}' | cut -d. -f1-3))
Cut split string with field delimiter (-d) , then you select desired field with -f param.
You could use this single awk script awk -F'[ .]' '{print $2"."$3"."$4}':
$ VERSION=$(awk -F'[ .]' '{print $2"."$3"."$4}' /path/file.spec)
$ echo $VERSION
3.12.0
Or this single grep
$ VERSION=$(grep -Po 'Version: \K\d+[.]\d+[.]\d' /path/file.spec)
$ echo $VERSION
3.12.0
But you never need grep and awk together.
if you only grep single file, -r makes no sense.
also based on the output of your command line, this grep should work:
grep -Po '(?<=Version: )(\d+\.){2}\d+' /path/file.spec
gives you:
3.12.0
the \K is also nice. worked for fixed/non-fixed length look-behind. (since PCRE 7.2). There is another answer about it. but I feel look-behind is easier to read, if fixed length.

Resources