How to use -o with grep to extract a number - regex

For example, if I try to run the command without the -o tag:
> grep '[0-9]*' <<< "ss1578130091522"
> ss1578130091522
If I try to run with the -o tag, I get this:
> grep -o '[0-9]*' <<< "ss1578130091522"
>
Why does it return me an empty line? Shouldn't it extract the number for me?
This is what I ideally want:
> grep -o '[0-9]*' <<< "ss1578130091522"
> 1578130091522
This is using zsh on macOS Catalina.

The regex [0-9]* matches the empty string, so that's what grep -o returns.
Try
grep -E -o '[0-9]+' <<<"ss1578130091522"
or
grep -o '[0-9]\+' <<<"ss1578130091522"
With -E, grep supports extended regular expression syntax.
Without -E, you have to use POSIX basic regular expression syntax, which
(insanely IMHO) requires the plus operator to be backslashed.
(The original grep from 1969 did not have this operator; that's why this syntax is "extended".)
You are clearly using zsh, not bash. These are two different, incompatible shells (though they share some features, and are both based on the Bourne shell sh).

Related

grep regex for return numerical values in between string

so i'm running the linux command
ls /etc/systemd/system | grep -o -E "[0-9]+"
which should return just numerical values, the only problem it returns some unwanted numerical values from parts of results i dont want, i want only the numerical values between - and .service so in like test-blah4-1321.service i just want it to return 1321. What am i missing here?
example
$ ls /etc/systemd/system
test.service test-blah4-1321.service test-blah2.service test-blah5-1387.service test-blah3-1521.service
GNU grep has the -P option for perl-style regexes, and the -o option to print only what matches the pattern. These can be combined using look-around assertions (described under Extended Patterns in the perlre manpage) to remove part of the grep pattern from what is determined to have matched for the purposes of -o.
Source
Applied to your example this would be:
echo test-blah4-1321.service | grep -oP '(?<=-)\d+(?=\.service)'
when I need look ahead or look behind tests I usually switch to a Perl one-liner.
this should do the trick.
echo test-blah4-1321.service | perl -ne 'm/(?<=-)(\d+)(?=\.service)/g; print "$1\n";'

Regex error "Repetition not preceded by valid expression" in Grep

I have in a file with strings such as {?ENV1} {?ENV2}
I want to use grep to find these using
grep -o '\{\?\S+?\}' myfile
but I get
grep: bad regex '\{\?\S+?\}': Repetition not preceded by valid expression
in regex101 website the regex works. Is grep working differently?
POSIX grep default regex engine is POSIX BRE. You shouldn't escape braces or use \S. Former leads to a special meaning (the cause of error you see) and latter isn't supported. Try:
grep -o '{?[^{}]*}' file
Or to keep \S purpose:
grep -o '{?[^[:space:]]*}' file
Or even to work around + quantifier:
grep -o '{?[^[:space:]][^[:space:]]*}' file
Use -P flag for Perl based regular expressions(though still in experimental phase)
grep -oP '\{\?\S*\}' myfile
OR
Try this with updated regex. You can use *
grep -o '\{\?\S*\}' myfile

Regular expression doesn't work in grep

Why grep doesn't match "COL1,COL2,COL3," with this regexp as expected but "COL1,COL2,COL3,COL4,COL5,COL6,"? It matches correctly in text editor but not using grep, am I missing any special escaping or..? (using OS X Lion)
The text:
COL1,COL2,COL3,COL4,COL5,COL6,COL7,COL8,COL9
The command:
grep -E --color=auto '^([^,]*,){3}' file.csv
Grep version:
grep (GNU grep) 2.5.1
Your command:
grep -E --color=auto '^([^,]*,){3}' file.csv
will only color the string COL1,COL2,COL3, differently but if you want that string in output then use -o option like this:
grep -E -o '^([^,]*,){3}'

regex for grep for screen resolution of the form 1280x720

I am trying to give grep a regex pattern for screen resolution(e.g. 1280x720) as following
[0-9]{3,}x[0-9]{3,}
but it doesn't seem to be working.
The following works but that doesn't translate to the above one.
[0-9][0-9][0-9][0-9]*x[0-9][0-9][0-9][0-9]*
That is an ERE (extended regular expression), grep uses BREs (basic regular expressions by default. You can either escape the {}:
grep '[0-9]\{3,\}x[0-9]\{3,\}'
or tell grep to interpret it as an ERE:
grep -E '[0-9]{3,}x[0-9]{3,}'
Your regex seems fine for bash :
[[ 1280x720 =~ [0-9]{3,}x[0-9]{3,} ]] && echo OK
OK
If you want to use grep :
$ cat B
640x480
$
$ grep -c "[0-9]\{3,\}x[0-9]\{3,\}" B
1
$
$ grep --version
grep (GNU grep) 2.14

Is it possible to invoke grep with a stored regular expression from a file?

I'm working on a nice long regular expression (for fun, yeah I know...) and I'd like to write it in a file so I can keep a better record of it. Can I call grep like this:
grep regex.txt fileToSearch.txt
I've tried it and it doesn't work. Are there any flags I have to use or is this approach not possible?
from man grep:
-f FILE, --file=FILE
Obtain patterns from FILE, one per line. The empty file contains zero patterns, and therefore matches nothing. (-f is specified by POSIX.)
Example:
$> cat ./file.txt
.*a
$> echo "abcabc" | grep -o -P -f ./file.txt
abca
What about
grep "$(cat regex.txt)" fileToSearch.txt
or
grep --file=regex.txt fileToSearch.txt