For example, I have a string like this: 1341 5415 fdad
.
Command grep -E "(^|\s)[1-9]{1,5}($|\s)" -o
will give only 1341
, but I want to get 1341
and 5415
.
How can I do this?
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It only takes a minute to sign up.
Sign up to join this communityecho '1341 5415 fdad' | grep -E -o '\b[1-9]{1,5}\b'
Output:
1341 5415
-E
: Interpret PATTERNS as extended regular expression
-o
: Print only the matched (non-empty) parts of a matching line, with each such part on a separate output line.
The actual match you get is 1341␣
, with the trailing space. And grep doesn't look for overlapping matches, so when that space is taken by the first match, the pattern doesn't match again on the rest of the line. But if the input was 123 456 789
, the two strings 123␣
and ␣789
would be matched.
It's probably easier to use grep -w
:
-w
,--word-regexp
Select only those lines containing matches that form whole words. The test is that the matching substring must either be at the beginning of the line, or preceded by a non-word constituent character.
$ echo '1341 5415 fdad' | grep -wE "[1-9]{1,5}" -o
1341
5415
Alternatively, you could double all spaces before the grep:
$ echo '1341 5415 fdad' | sed -e 's/ / /g' | grep -E "(^|\s)[1-9]{1,5}($|\s)" -o
1341
5415
(or with sed -e 's/\s/ /g'
if that works in your sed.)
There's a trailing space in 1341
line, and a leading one in the 5415
, those are part of the matches.
One method is to change all spaces to a newline, then use grep -x
to select lines that exactly match your expression:
$ echo '1341 5415 fdad' | tr -s '[:space:]' '[\n*]' | grep -xE -e '[1-9]{1,5}'
1341
5415
tr -s '[:space:]' '\n'
since tr
is supposed to extend the second list of characters by repeating the last one as necessary to match the length of the first