Reputation: 24778
I have this:
echo 12345 | grep -o '[[:digit:]]\{1,4\}'
Which gives this:
1234
5
I understand whats happening. How do I stop grep from trying to continue matching after 1 successful match?
How do I get only
1234
Upvotes: 10
Views: 32748
Reputation: 1
grep manpage says on this topic (see chapter 'regular expressions'):
(…)
{n,}
The preceding item is matched n or more times.
{n,m}
The preceding item is matched at least n times, but not more than m times.
(…)
So the answer should be:
echo 12345 | grep -o '[[:digit:]]\{4\}'
I just tested it on cygwin terminal (2018) and it worked!
Upvotes: 0
Reputation: 770
If – as in your example – your numeric expression will appear at the beginning of the string you're starting with, you could just add a start-of-line anchor ^
:
echo 12345 | grep -o '^\([[:digit:]]\)\{1,4\}'
Depending on which exact digits you want, an end-of-line anchor $
might help also.
Upvotes: 0
Reputation: 2231
You need to do the grouping: \(...\)
followed by the exact number of occurrence: \{<n>\}
to do the job:
maci:~ san$ echo 12345 | grep -o '\([[:digit:]]\)\{4\}'
1234
Hope it helps. Cheers!!
Upvotes: 6
Reputation: 755016
Use sed
instead of grep
:
echo 12345 | sed -n '/^\([0-9]\{1,4\}\).*/s//\1/p'
This matches up to 4 digits at the beginning of the line, followed by anything, keeps just the digits, and prints them. The -n
prevents lines from being printed otherwise. If the digit string might also appear mid-line, then you need a slightly more complex command.
In fact, ideally you'll use a (A semi-solution to a considerably more complex problem...now removed!)sed
with PCRE regular expressions since you really need a non-greedy match. However, up to a reasonable approximation, you can use:
Since you want the first string of up to 4 digits on the line, simply use sed
to remove any non-digits and then print the digit string:
echo abc12345 | sed -n '/^[^0-9]*\([0-9]\{1,4\}\).*/s//\1/p'
This matches a string of non-digits followed by 1-4 digits followed by anything, keeps just the digits, and prints them.
Upvotes: 3
Reputation: 53516
Do you want grep to stop matching or do you only care about the first match. You could use head
if the later is true...
`grep stuff | head -n 1`
Grep is a line based util so the -m 1
flag tells grep to stop after it matches the first line which when combined with head is pretty good in practice.
Upvotes: 10