开发者

extract a quoted value from multiple lines using sed

I'm a total n00b when it comes to using sed and can't quite figure this out...

I've got the following data being output by a command line tool:

ruby:
interpreter:  "ruby"
version:      "1.8.6"
date:         "2010-02-04"
platform:     "i386-mingw32"
patchlevel:   "398"
full_version: "ruby 1.8.6 (2010-02-04 patchlevel 398) [i386-mingw32]"

homes:
gem:          ""
ruby:         "C:\ruby\ruby-1.8.6-p398-i386-mingw32"

binaries:
ruby:         "C:\ruby\ruby-1.8.6-p398-i386-mingw32\bin"
irb:          "C:\ruby\ruby-1.8.6-p398-i386-mingw32\bin\irb.bat"
gem:          "C:\ruby\ruby-1.8.6-p398-i386-mingw32\bin\gem.bat"
rake:         ""

environment:
GEM_HOME:     ""
HOME:         "c:/Users/derick"
IRBRC:        ""
RUBYOPT:      ""

file associations:
.rb:
.rbw:

I want to use sed to extract the values from interpreter and version only, and have them returned as "interpreter-version".

The best I could come up with so far is to use grep to return the entire version line:

pik info | grep -e '^version:.*'

but that returns too much info from the version line, and doesn't include the interpreter (obviously).

How can i use sed to extract only the bits of information that i want, so that i get a result of ruby-1.8.6?

... or grep, or awk, or any other command line tool to get the info i want...

FWIW: i'm not using RVM because this is a windows machine using MinGW32... i'开发者_运维百科m using Pik, which is similar to RVM but made for windows.


A lot of you are working hard to deal with the quotes. Let awk do it:

pik info | awk -F '"' '
    /^interpreter:/ {interp = $2} 
    /^version:/     {ver = $2}
    interp && ver   {print interp "-" ver; exit}
'


Would working with the 'full_version' string be useful?

pik info | awk '/full_version/ {print $2,$3}' | sed 's/\"//;s/\s/\-/'

I'm certain the sed bit could be folded into the awk bit with 'sub()', but I'll leave it to someone more versed in awk.


It is easy enough to do in pure 'sed' if you're aware of the 'hold space':

sed -n '/^interpreter: *"\(.*\)"/{
s//\1/
h
}
/^version: *"\(.*\)"/{
s// \1/
H
x
s/\n//
s/.*/interpreter-version: "&"/p
}'

The script overall doesn't print anything (-n) unless you command it to. The first pattern searched for is the interpreter line; we capture the name of the interpreter, then remove all the rest of the material, and copy the interpretr name (plus a newline) into the hold space ('h'). The second pattern searched for is the version string. We similarly isolate just the version number - prefixing it with a space. Then we concatenate the version number to the hold space ('H'), and swap the hold and pattern spaces ('x'). We remove the newline in between the interpreter name and the version number; then prefix it with 'interpreter-version: "' and follow it with a closing double quote and print the result:

interpreter-version: "ruby 1.8.6"

And if what you really want is 'ruby-1.8.6', then the changes are minor:

sed -n '/^interpreter: *"\(.*\)"/{
s//\1/
h
}
/^version: *"\(.*\)"/{
s//-\1/
H
x
s/\n//p
}'

This prefixes the version with a dash instead of a space, and then only has to remove the newline before printing after exchanging the hold and pattern spaces.


1) capture to file what's being output by your command line tool i.e. something >> outfile 2) on my bash/ubuntu box"

grep -e "interpreter" -e "version" outfile | awk 'BEGIN {print"Interpreter-Version" }{print $2}'| sed 's/"//g'| tr '\n' ' '

3) The output:

Interpreter-Version ruby 1.8.6

I am sure it could be optimized but it worked for me :-)

HTH,

Chris.


This should do the trick:

pik info | awk '/^interpreter:/ {inter=$2; gsub(/"/, "", inter)} /^version:/ {vers=$2; gsub(/"/, "", vers)} END {print inter "-" vers}'

generates ...

ruby-1.8.6


A version using both awk and sed.

pik info | awk '/^interpreter:|^version:/ {printf "%s-", $2}' | sed -e 's/"//g' -e 's/-$//'


Using only sed:

pik info | sed -n '/^full_version: "\([^(]*\)(.*/ {s//\1/; s/ /-/;p}'
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜