Find and extract a number from a file

Viewed 76

So I want to create script to update a version number.

The file contents look like this. I struggle to extract the number from the file. I want to extract and parse the number "58" The other numbers might also change. The file contents look like this.:

# Some more lines above
    pod 'Alamofire', :git => 'https://github.com/Alamofire/Alamofire.git', :tag => '0.2.58'
# More lines below

My approach was to use grep -o Alamofire.git.*[0-9].[0-9].[0-9]+ ../Podfile

But this doesn't work. Is there any easy solution to this?

3 Answers

With your shown samples and in any awk version please try following awk code. Here is the Online demo for used regex (^[[:space:]]+pod \047Alamofire\047, :git => \047https?:\/\/github\.com\/.*\/Alamofire\.git\047, :tag => \047([0-9]+\.)+[0-9]+\047) to get needed values by OP.

awk '
match($0,/^[[:space:]]+pod \047Alamofire\047, :git => \047https?:\/\/github\.com\/.*\/Alamofire\.git\047, :tag => \047([0-9]+\.)+[0-9]+\047/){
  val=substr($0,RSTART,RLENGTH)
  gsub(/.*\.|\047$/,"",val)
  print val
}
'   Input_file

Explanation: Adding detailed explanation for above regex.

^[[:space:]]+pod   ##From starting of value matching space(s) followed by string pod followed by a space.
\047Alamofire\047, ##Matching ' followed by Alamofire followed by ' and comma here.
:git => \047https? ##Matching :git space => followed by ' http and keeping s optional(to match http also).
:\/\/github\.com\/ ##Matching colon // github.com followed by a / here.
.*\/Alamofire\.git ##Matching everything till / followed by Alamofire followed by .git here.
\047, :tag => \047 ##Matching ', followed by space :tag followed by space => followed by space and ' here.
([0-9]+\.)+        ##Matching digits(1 or more occurrences) followed by dot and this whole group 1 or more times.
[0-9]+\047         ##Matching 1 or more digits followed by a ' here.

If you can use ggrep

ggrep -oP 'Alamofire\.git.*[0-9]\.[0-9]\.\K[0-9]+' ../Podfile

Output

58

Another option with awk and a bit more specific match setting the . and ' as a field separator:

awk -F"[.']" '
match ($0, /Alamofire\.git.*\047[0-9]+\.[0-9]+\.[0-9]+\047$/) {
  print $(NF-1)
}' file

Or with gnu-awk and a capture group:

gawk 'match($0, /Alamofire\.git.*[0-9]\.[0-9]\.([0-9]+)/, a) {print a[1]}' ../Podfile

With GNU Grep:

grep -o -P 'Alamofire.*:tag.*\.\K\d+' file

Sed:

sed -nE 's/.*Alamofire.*\.([[:digit:]]*).*/\1/p' file

Awk:

awk -F. '/Alamofire/{gsub(/[^[:digit:]]/,"", $NF); print $NF}' file

POSIX grep native on MacOS you can use a pipe:

grep 'Alamofire' file | tr -d [\'\"] | rev | cut -d'.' -f 1 | rev
Related