0

I got a file so something like:

helsoidfiejoih
heye heye hey 
me is hi

The file can have any number of lines or characters in it the point is that it is a text file of some sort. Now the I need to use grep to do some operation so that the first parameter passed to grep is the filename and the second parameter is the pattern. But grep does a greedy match so it matches the whole line instead of a non greedy match which is what I want(non-greedy match). Now I tried:

grep -Ec -Po "$2" $1

It gives me conflicting expressions. And the user can enter any pattern A.K.A RE so the -E is a necessary option. Is there a way to make the grep non-greedy? I was told that the -P option makes the grep command non greedy but after trying out:

grep -c -Po "$2" $1

It does not seem to make the grep expression non greedy??

Edit: People said Im not showing the patterns I working with so to clarify the patterns will be a RE so for example if the user inputs in

./thisfile.sh h file1.txt

It will find the number of times h appears in file1.txt If the user inputs in

./thisfile.sh io file1.txt

It will find the number of times io appears in file1.txt. Is there a way to do this?

4
  • You never show the pattern(s) that you're trying with. Also, -E and -P enables extended regular expressions (ERE) and Perl-compatible regular expressions (PCRE), respectively. You cannot get both. This is what the error ("conflicting matchers specified") tells you. What do you want, PCRE or ERE? Also note that while -o gives you one line per match, the -c option will cancel the effect of -o and only return the number of lines matched. It is unclear what your intention is with this. You also fail to quote $1 and your command fails if the pattern in $2 start with a dash.
    – Kusalananda
    Jun 11, 2021 at 18:46
  • I want extended regular expressions but I was told -P makes it non greedy by Stackoverflow?? Jun 11, 2021 at 19:53
  • 2
    -P does not make your regular expressions non-greedy automatically. The -P option enables Perl-compatible regular expressions (these are different from extended regular expressions enabled with -E). These can be greedy or non-greedy, depending on how you write them. Ordinary regular expressions (with or without -E) can probably be used too, but would have to be written to not match greedily across substrings that you don't actually want to match.
    – Kusalananda
    Jun 11, 2021 at 20:10

2 Answers 2

1

To count how many times a substring occurs in a file:

#!/bin/sh

grep -F -o -e "$1" | wc -l

You would use this script like so:

$ ./script e <script
       2
$ ./script ' -' <script
       4
$ ./script hey <file1
       3
$ ./script he <file1
       4
$ df | ./script %
       7

Here I'm counting the number of e characters in the script itself, and then the number of times the substring consisting of a space and a dash occurs in the script. Then I count a couple of substrings in the file presented in the question. The last example counts the number of percent signs in the output of df on my system.

The input data is read though standard input and the script's only argument is the substring that we want to look for and count.

The script consists of a single grep+wc pipeline. It uses the non-standard (but commonly implemented) -o option to return a list of non-overlapping matches on separate lines. These lines are then counted with wc -l.

The call to grep uses -F to make the pattern be interperted as a string and not as a regular expression. This makes it possible to count the number of times e.g. * occurs in a file, without having to escape the * (you would still have to quote the * to stop the shell from using it as a globbing pattern though). Leave -F out if you want to use the pattern as a regular expression.

The -e option is used to tell grep that $1 is the pattern. If -e is not used, a pattern like --version would be interpreted as an option to grep.

0

Some versions of grep (e.g. GNU's) allow you to give Perl compatible REs (check out PCRE), those are much more flexible than standard POSIX regexes.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .