0

I would like to grep a number of documents by using a set of search terms and to specify the number of characters after match. Here is what I tried

grep  -F -o -P "$(<search.txt).{0,4}" foo.txt

but I get the message 'grep: conflicting matchers specified' because -F and '-oP' cannot be combined. It does not work with '-E' either.

8
  • What are the contents of search.txt exactly? What sort of match are you trying to do exactly? {0,4} is a modifier for the atom directly before it (so to match whatever you get out of search.txt and four more characters you need .{0,4}). Commented Mar 27, 2015 at 19:57
  • How about trying to handcraft a grep command that matches any of "dog" or "cat" followed by four letters, and then seeing if you can turn a search.txt containing "dog" and "cat" into that command. Commented Mar 27, 2015 at 20:05
  • search.txt contains a list of terms and names. You're right with .{0,4} I made a mistake above, I'll correct it. Commented Mar 27, 2015 at 20:06
  • @that other guy, matching is not a problem, the search does match search terms properly but it shows the whole lines and I want to see only zero or four letters following my search terms. Commented Mar 27, 2015 at 20:09
  • @user3635159 does that mean you were able to handcraft a grep command that matches any of "dog" or "cat" followed by 0 or 4 letters? What was it? If you put an echo in front of that command and this command, do you find a difference? Commented Mar 27, 2015 at 20:19

1 Answer 1

2

-F and -P are conflicting options, simple as that. The first means that the patterns are fixed strings, the second means that the patterns are Perl-compatible regular expressions. Perhaps you meant to use -f instead, which reads patterns from a file or a process substitution.

If you want to match any of the patterns in your file, followed by 4 characters, you could use something like this

grep -oP -f <(awk '{print $0 ".{4}"}' search.txt) file

This dynamically adds the pattern to each line in the file.

Alternatively, a more portable and concise version would be this:

sed 's/$/.{0,4}/' search.txt | grep -f - -oP file
Sign up to request clarification or add additional context in comments.

6 Comments

I would prefer sed 's/$/.{0,4}/' search.txt | grep -f - -oP foo.txt but perhaps it's a matter of taste.
Thanks for your explanation. Both suggestions work. In Cygwin at least the option with -P won't work - I get the message "grep: the -P option only supports a single pattern". If -E is used instead it will work. What would be the option to search on both sides?
sed 's/.*/.{0,4}&.{0,4}/' adds a predix as well.
We can't tell if the -P is really necessary when we don't know what your patterns look like. If it is, you could smash them all together into one with something like sed ‘1s/^/.{0,4}(?:/;$!s/\n/|/;$s/$/).{0,4}/'.
... or just switch to Perl (-: or an existing concordance tool, since that seems to be what you are doing?
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.