Sed: Extract version number from string

Input: adcheck (CentrifyDC 4.4.3-421)

Required Conclusion: 4.4.3

What I thought would work:

 /usr/share/centrifydc/bin/adcheck --version | sed -n '/Centrify DC /,/-/p' 

But it doesn’t output anything

Thank!

+3
sed
Jul 11 '11 at 19:19
source share
6 answers
 sed 's/[[:alpha:]|(|[:space:]]//g' | awk -F- '{print $1}' <<< "(CentrifyDC 4.4.3-421)" 

output: 4.4.3

Use [:space:] to remove extra spaces.

sed used to remove unwanted characters, and awk -F- means use as a field separator

+5
Jul 11 '11 at 19:35
source share

Your solution does not work because you are trying to use addresses to select part of a string, but the addresses just select a bunch of strings. Your code /Centrify DC /,/-/p will print all lines between one line containing Centrify DC and another line containing - . It does not work only inside one line, however

You want to remove everything from the string except the version number. I would recommend that you group the version number and replace the entire contents of the string with it:

 $ echo "adcheck (CentrifyDC 4.4.3-421)" | sed 's/^.*[^0-9]\([0-9]*\.[0-9]*\.[0-9]*\).*$/\1/' 4.4.3 

Here we put the version number in the group with \([0-9]*\.[0-9]*\.[0-9]*\) and replace the entire line with the group (via the link \1 ).

If your input has more than one line, some tunneling may be required:

 $ cat file adcheck (CentrifyDC 4.4.3-421) another line still another line $ sed 's/^.*[^0-9]\([0-9]*\.[0-9]*\.[0-9]*\).*$/\1/' file 4.4.3 another line still another line 

In this case, pass the -n flag to sed to prevent printing by default. Then give the address to the s/// command (for example, /adcheck (CentrifyDC / ) to ensure that the replacement will occur only on the line that matches the address. Finally add the p flag to the s/// command - it will print the line immediately after the replacement :

 $ sed -n '/adcheck (CentrifyDC /s/^.*[^0-9]\([0-9]*\.[0-9]*\.[0-9]*\).*$/\1/p' file 4.4.3 
+3
Jul 11 '11 at 19:44
source share

The corrected version of “What do you think will work”:

 /usr/share/centrifydc/bin/adcheck --version | sed 's|.*CentrifyDC \([0-9\.]*\).*|\1|' 

Output:

 4.4.3 
+3
Jul 11 2018-11-11T00:
source share

single line perl script

 perl -pe '($_)=/([0-9]+([.][0-9]+)+)/' YOURFILE.TXT 

or a little longer, but it processes several versions:

 perl -nle 'print $v if ($v)=/([0-9]+([.][0-9]+)+)/' YOURFILE.TXT 

examples using the first command line

 $> V=$(perl -pe '($_)=/([0-9]+([.][0-9]+)+)/'<<<'adcheck (CentrifyDC 4.4.3-421)') $> echo "$V" 4.4.3 $> V=$(perl -pe '($_)=/([0-9]+([.][0-9]+)+)/' <<< 'dos2unix-8.2.3-beta.zip') $> echo "$V" 8.2.3 $> echo 'A2 33. Z-0.1.2.3.4..5' | perl -pe '($_)=/([0-9]+([.][0-9]+)+)/' 0.1.2.3.4 $> gcc --version | perl -pe '($_)=/([0-9]+([.][0-9]+)+)/' 4.7.3 $> bash --version | perl -pe '($_)=/([0-9]+([.][0-9]+)+)/' 4.2.45 $> meld --version | perl -pe '($_)=/([0-9]+([.][0-9]+)+)/' 1.6.1 $> uname -a | perl -pe '($_)=/([0-9]+([.][0-9]+)+)/' 3.8.0 $> perl -pe '($_)=/([0-9]+([.][0-9]+)+)/' /etc/issue 13.04 

Note. the first command line retrieves the version without a final carriage return (I mean \n ). If this is a problem, use the second version or complete the first command line in echo :

 $> echo $( perl --version | perl -pe '($_)=/([0-9]+([.][0-9]+)+)/' ) 5.14.2 

Unfortunately, if there are several lines containing version numbers, these version numbers will be merged:

 $> echo $(gwenview --version | perl -pe '($_)=/([0-9]+([.][0-9]+)+)/' ) 

4.8.44.10.54.10.4

To extract one version for each line, you need to modify a single-line script:

 perl -pe 'if(($_)=/([0-9]+([.][0-9]+)+)/){$_.="\n"}' 

Example:

 $> gwenview --version | perl -pe 'if(($_)=/([0-9]+([.][0-9]+)+)/){$_.="\n"}' 4.8.4 4.10.5 4.10.4 

To extract only the first version number and add a carriage return (I mean the new line \n ), I advise:

 perl -pe 'if(($v)=/([0-9]+([.][0-9]+)+)/){print"$v\n";exit}$_=""' 

example:

 $> gwenview --version | perl -pe 'if(($v)=/([0-9]+([.][0-9]+)+)/){print"$v\n";exit}$_=""' 4.8.4 



For information, sed is not so good. Who knows how to get the same behavior as my perl scripts, but using sed ?

 sed 's/\([0-9][0-9]*[.][0-9][0-9.]*\)/\n\1/' 



If you think you can improve these scenarios, feel free to leave comments :)

+3
26 Oct '13 at 6:40
source share

Here's the solution in Perl:

 echo "adcheck (CentrifyDC 4.4.3-421)" | perl -ne 'm/adcheck \(CentrifyDC (.*?)\)/; print "$1\n" ' /usr/share/centrifydc/bin/adcheck --version | perl -ne 'm/adcheck \(CentrifyDC (.*?)\)/; print "$1\n" ' 
+1
Jul 11 '11 at 19:24
source share

Another approach using only awk :

 $ echo "adcheck (CentrifyDC 4.4.3-421)" | awk '{sub(/-.*/,"",$3);print $3}' 4.4.3 

... or perhaps a cut combination:

 $ echo "adcheck (CentrifyDC 4.4.3-421)" | cut -d' ' -f3 | cut -d'-' -f1 4.4.3 
+1
Jul 11 2018-11-11T00:
source share



All Articles