Use grep to match a pattern in a string only once.

I have it:

echo 12345 | grep -o '[[:digit:]]\{1,4\}' 

What gives this:

 1234 5 

I understand what is happening. How to stop grep from trying to continue matching after 1 successful match?

How do I get only

 1234 
+7
source share
5 answers

You need to group: \(...\) , followed by the exact number of occurrences: \{<n>\} to complete the job:

 maci:~ san$ echo 12345 | grep -o '\([[:digit:]]\)\{4\}' 1234 

Hope this helps. Hooray!!

+5
source

Do you want grep to stop matching or you only care about the first match. You can use head if the latter is true ...

 `grep stuff | head -n 1` 

Grep is line-based use, so the -m 1 flag tells grep to stop after it matches the first line, which when combined with the head is pretty good in practice.

+7
source

Use sed instead of grep :

 echo 12345 | sed -n '/^\([0-9]\{1,4\}\).*/s//\1/p' 

This corresponds to 4 digits at the beginning of a line followed by something, saves only the digits and prints them. -n prevents printing lines otherwise. If a string of numbers can also appear in the middle line, you will need a slightly more complex command.

In fact, ideally, you'll use sed with PCRE regular expressions, since you really need a non-greedy match. However, until a reasonable approximation, you can use: (Semi-solution for a more complex problem ... now deleted!)

Since you want the first line to be up to 4 digits long per line, just use sed to delete any numbers, and then print the number line:

 echo abc12345 | sed -n '/^[^0-9]*\([0-9]\{1,4\}\).*/s//\1/p' 

This corresponds to a line without digits, followed by 1-4 digits, followed by something, saves only the digits and prints them.

+3
source

If - as in your example - your numeric expression appears at the beginning of the line you start with, you can simply add an anchor to the beginning of the line ^ :

 echo 12345 | grep -o '^\([[:digit:]]\)\{1,4\}' 

Depending on the exact digits you want, snapping the end of the string $ may also help.

0
source

people of the past

my answer to post number 1 of this topic

On this topic grep manpage (see the "Regular Expressions" chapter):

(...)

{n,} The previous item matches n or more times.

{N, t}

The previous element is matched at least n times, but no more than m times.

(...)

(see web search on the "grep man page, Cygwin flavor")

Given the correctness of the manual, the answer to your question in post number 1 should be as follows:

  echo 12345 | grep -o '[[:digit:]]\{4\}' 

I just tested it on the Cygwin terminal (2018) and it works!

0
source

All Articles