0

I'm looking to find a grep command to search for all words/string that contain the letter q that is not followed by a u directly after.

grep 'q!u' file
  • How do you define word/string? – Michael Homer Mar 24 at 22:01
3

The GNU grep implementation of grep that you have on Linux is able to use PCRE-style "negative look-ahead assertions". PCRE is short for "Perl compatible regular expressions". These are extensions to the standard POSIX regular expressions and the syntax for what you want to do looks like

q(?!u)

With GNU grep:

grep -P 'q(?!u)' file

would find all lines that contains a q that is not followed (directly) by a u.

Further information on lookaround assertions with PCRE may be found at, for example


A POSIX standard regular expression could use

q[^u]

i.e., "a q followed (directly) by something that is not a u". However, this pattern also matches the non-u character, whereas the expression with the negative look-ahead does not match the character after the q. This means that the above expression would not match a q at the end of a line, for example. To do that, you could possibly use

q([^u]|$)

which is an extended regular expression (use grep with -E for this).


As for you "word/string": A word is a string of word characters, usually characters matching [[:alpha:]]. A string is any string. The q(?!u) expression at the top would match any string that contained a q not followed (directly) by a u.

To match words containing a q but not the sequence qu, you could do either

grep -P -o -w '[[:alpha:]]*q(?!u)[[:alpha:]]*'

i.e. extract all complete words (only) that contains a q not followed by a u, or you could do it in two steps:

grep -o -w '[[:alpha:]]*q[[:alpha:]]*' | grep -v qu

This one would not require a PCRE (and hence no -P) and would get all words containing a q and then remove (with the second grep) the words that contained qu.

Example:

$ grep -o -w '[[:alpha:]]*q[[:alpha:]]*' /usr/share/dict/words  | grep -v qu
Iraq
Iraqi
Iraqian
Louiqa
miqra
nastaliq
Pontacq
q
qasida
qere
qeri
qintar
qoph
Saqib
shoq
Tareq

The PCRE variant would additionally return zaqqum as that contains a q not followed by a u.

Whichever way you do this depends on what your data looks like and what you actually want to match.

  • I wonder if "word ends in q" is a condition that needs to be matched – Stephen Harris Mar 24 at 22:20
  • 1
    grep -E 'q([^u]|$)' (instead of grep 'q[^u]') to catch a q at the end of a line – ilkkachu Mar 24 at 22:42
  • @ilkkachu Thanks. Incorporated. – Kusalananda Mar 24 at 22:46
0

I have done by below awk command

example file

prqrtwtw
ahayqlo
prasqu

expected output

prqrtwtw
ahayqlo

command:

k=`awk -F "" '{print NF}' examplefile | sort -nr | sed -n '1p'`

for ((i=1;i<=$k;i++))
> do
> awk -v i="$i" -F "" '$i=="q" && $(i+1) !="u"  {print $0}' examplefile;done




output

prqrtwtw
ahayqlo

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.