14

I'm using this regex (?<=\[')[^,]* on a file containing the following line disk = ['OVS/sdasd/asdasd/asdasd/something.img, w']

I want that to return OVS/sdasd/asdasd/asdasd/something.img

How do I use grep to make it work?

I've tried grep -P "(?<=\[')[^,]*" but it returns the whole line.

GxFlint
  • 305
  • 1
  • 2
  • 9

3 Answers3

20

Add the -o switch so that grep only returns what matches the pattern you're grepping for:

$ grep -Po "(?<=\[')[^,]*" data.txt 
OVS/sdasd/asdasd/asdasd/something.img
slm
  • 369,824
6

You can also use sed without the lookaround assertion for greater portability (-o may not be available for your grep):

sed "s!['\(\[^,\]*\),.*\$!\1!;t;d;p" data.txt

Note the "strange" use of backslash escapes here. It's due to the fact that sed uses BREs by default (see this question).

Speaking of portability, why not just use Perl?

perl -nle "print \$1 if /\['([^,]*)/" data.txt
Joseph R.
  • 39,549
2

@slm already gave you the canonical answer. Here are a few more options:

Use awk and ' as field delimiter (assuming all lines have the same format):

$ awk -F "'" '($1~/ = /){print $2}'
OVS/sdasd/asdasd/asdasd/something.img, w    

Do the whole thing in perl:

$ perl -lne 'print $1 if /\[.(.*?).\]/' data.txt 
OVS/sdasd/asdasd/asdasd/something.img, w    

Use a simpler regex and parse the results:

$ grep "\[.*\]" data.txt | awk -F "'" '{print $2}'
OVS/sdasd/asdasd/asdasd/something.img, w
$ grep -o "\[.*\]" data.txt | perl -pe "s/[\[\]']//g"
OVS/sdasd/asdasd/asdasd/something.img, w
$ grep "\[.*\]" data.txt | sed 's/.*\[.\(.*\).\]/\1/'
OVS/sdasd/asdasd/asdasd/something.img, w
$ grep "\[.*\]" data.txt | perl -pne 's/.*\[.(.*?).\].*/$1/'
OVS/sdasd/asdasd/asdasd/something.img, w
$ grep "\[.*\]" data.txt | perl -lne 'print $1 if /\[.(.*?).\]/'
OVS/sdasd/asdasd/asdasd/something.img, w
terdon
  • 242,166