How to grep my one-line file with constant key?

41 Views Asked by At

This is my file

__version__="1.11.10"

numerical part will change all the time and I want to grep this.

new_tag=`grep -Eo '[0-9]+\.[0-9]+\.[0-9]+'_version.py`

failed. how to extract 1.11.10 ?

3

There are 3 best solutions below

0
Wiktor Stribiżew On BEST ANSWER

You may use sed:

sed -n 's/.*="\([^"]*\)"/\1/p' file

To assign to a variable:

new_tag=$(sed -n 's/.*="\([^"]*\)"/\1/p' file)

See the online Bash demo.

Details

  • -n - suppresses default line output in the sed command
  • .*="\([^"]*\)" - a POSIX BRE pattern that matches
    • .* - any text then
    • =" - a =" string
    • \([^"]*\) - capturing group #1 that captures zero or more chars other than "
    • " - a " char
  • \1 - replaces the match with Group 1 contents
  • p - prints the resulting value
1
Gilles Quénot On

What I would do:

grep -oP '__version__="\K[^"]+'

  • -o display only the matched part
  • -P allow PCRE regexes

The backquote is used in the old-style command substitution. The foo=$(command) syntax is recommended instead. Backslash handling inside $() is less surprising, and $() is easier to nest. See http://mywiki.wooledge.org/BashFAQ/082

So use:

variable=$(grep ....)

The regular expression matches as follows:

Node Explanation
__version__=" as is
\K resets the start of the match (what is Kept) as a shorter alternative to using a look-behind assertion: look arounds and Support of \K in regex
[^"]+ any character except: " (1 or more times (matching the most amount possible))
0
The fourth bird On

The regex for you expected value works, but you should update the syntax to using a sub shell:

new_tag=$(grep -Eo '[0-9]+\.[0-9]+\.[0-9]+' file)

Or as an alternative using gnu awk matching the string with a capture group, and then print the capture group 1 value:

new_tag=$(awk 'match($0, /__version__="([0-9]+\.[0-9]+\.[0-9]+)"/, a){print a[1]}' file)