2

This is a pretty basic question, but I can't get my head around it. I'm learning Linux and one of the questions i've been given is;

*The word sentimentalment includes the same three characters (e.g. "ent") which appear three times. The word "blayblapblam" also contains the same three characters repeated three time (e.g. "bla").

How many words can you find which contain any three characters repeated three times, like the examples "sentimentalment" and "blayblapblam", but which also begin with lower case "d". Use /usr/share/dict/words as your list of possible words and grep to find the answer. The "d" is not one of the characters considered when detecting the three-character strings.*

So far, I can return instances where the same three letters appear twice;

grep -E '^d(...).*\1' /usr/share/dict/words > output

Which to me reads, look for a word beginning with 'd', then combination of three letters, 0 or more characters before the same group (1) appearing again.

I've tried the following;

grep -E '^d(...).*\1.*\1' /usr/share/dict/words > output

Which if my understanding is correct (which it obviously isn't), returns group one, then zero or more characters, then group one again.

Can someone point out where I'm going wrong? Any help is appreciated.

  • Just to avoid any confusion, neither "sentimentalment" nor "blayblapblam" are words or even common proper nouns in the English language, which is what I assume /usr/share/dict/words contains. I was unable to find any words that match the pattern described above in my local words file. – jw013 Nov 1 '12 at 14:36
  • The POSIX standard removed the support of back-references for extended regular expressions, so you can't rely on all grep versions supporting it. To be safe, use basic regular expressions, which even makes the command shorter in this case: grep '^d.*\(...\).*\1.*\1' – Philippos Nov 3 '17 at 7:36
9

It seems you fixed the three letters to go right after the d. Perhaps you would need something like this instead:

grep -E '^d.*(...).*\1' /usr/share/dict/words > output

which would make your 3-pattern search into

grep -E '^d.*(...).*\1.*\1' /usr/share/dict/words > output

For portability reasons one should avoid combining extended regular expressions with back-references, so better use

grep '^d.*\(...\).*\1.*\1' /usr/share/dict/words > output

  • I believe this answer is exactly what you need. Bear in mind that on my system it returns no results from /usr/share/dict/words. It is, nevertheless, correct. – terdon Nov 1 '12 at 14:28
  • @terdon I don't have /usr/share/dict/words but tried it on some sample input, and it seems to have behaved as expected. – gt6989b Nov 1 '12 at 14:42
  • yes it does, absolutely, that's why I upvoted it :). I am just warning the OP that if there is no output, it does not mean that your solution is wrong. – terdon Nov 1 '12 at 15:16
  • @terdon Thank you... wonder why it takes forever to get such one-liners accepted... – gt6989b Nov 1 '12 at 15:38
  • 2
    @Utku no, grep will print any line as long as part of the line matches the pattern given. You don't need to match the entire line. – terdon Jun 18 '16 at 17:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.