Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Display only matched string with grep

I have a file that I want to match that looks like the following:

...
new VideoInfo(6, VideoType.Flash, 270, false, AudioType.Mp3, 64, AdaptiveType.None),
new VideoInfo(13, VideoType.Mobile, 0, false, AudioType.Aac, 0, AdaptiveType.None),
new VideoInfo(17, VideoType.Mobile, 144, false, AudioType.Aac, 24, AdaptiveType.None),
... [a few hundred more entries like these]

And I have the following regex pattern to match the first number:

grep "new VideoInfo(.*," VideoInfo.cs

The trouble is, grep emits the entire line that was matched instead of just 6 13 17 ....

How can I get it to echo only the matched results?


EDIT: I have trailing whitespace in front of each new VideoInfo ... line.

like image 948
James Ko Avatar asked Jul 09 '15 00:07

James Ko


People also ask

How do I print only a grep matched string?

Grep: Print only the words of the line that matched the regular expression, one per line. We used the following parameters on our command: -h, –no-filename : Suppress the prefixing of file names on output. This is the default when there is only one file (or only standard input) to search.

How do you grep for a word and display only the word?

The easiest of the two commands is to use grep's -w option. This will find only lines that contain your target word as a complete word. Run the command "grep -w hub" against your target file and you will only see lines that contain the word "hub" as a complete word.

How do I print grep output?

The grep command prints entire lines when it finds a match in a file. To print only those lines that completely match the search string, add the -x option. The output shows only the lines with the exact match.

Does grep return a string?

The grep command searches a text file based on a series of options and search string and returns the lines of the text file which contain the matching search string.


3 Answers

Using grep

If your grep supports the -P option for perl-style regex:

$ grep -oP '(?<=new VideoInfo\()[^,]*' file
6
13
17

(?<=pattern) is a look-behind. Thus, the above matches on the regex [^,]* but only if that regex is preceded by new VideoInfo\(.

Using sed

sed is a good match to this problem:

$ sed -nr 's/[[:space:]]*new VideoInfo\(([^,]*),.*/\1/p' file
6
13
17

Using bash

$ re='new VideoInfo\(([^,]*)'
$ while read -r line; do [[ $line =~ $re ]] && echo "${BASH_REMATCH[1]}"; done< file
6
13
17
like image 59
John1024 Avatar answered Sep 22 '22 05:09

John1024


You need to use -o (only-matching) and -P (Perl-regexp) parameters.

grep -oP '\bnew VideoInfo\(\K\d+' VideoInfo.cs

\b called word boundary which matches between a word char and a non-word character.(vice-versa) . \K is same as positive look-behind where the lookbehinds won't support any quantifiers but \K does. ie, we may use foo[^,]*,\K\d+ but we can't do (?<=foo[^,]*,)\d+ because lookbehinds won't allow quantifiers *, ?, + to be present inside them (PCRE only).

or

grep -oP '^\s*new VideoInfo\(\K[^,]*' VideoInfo.cs
like image 31
Avinash Raj Avatar answered Sep 21 '22 05:09

Avinash Raj


This will do:

grep -o pattern file

-o is for only match.


Your regex won't do what you want. Use Perl regex instead:
grep -oP "(?<=\bnew VideoInfo\().*?(?=,)" file

(?<=pattern) is look behind and (?=pattern) is look ahead, both are excluded in the matched string in grep.

like image 27
Jahid Avatar answered Sep 21 '22 05:09

Jahid