I have the following command to extract string that do not start with www. and do not contain /:

grep -v -e '^www\.' -e '/' test2.txt 

But I want the above in addition to matching somestring.somestring pattern, which can be achieved with this command:

grep -e '^[^\.]*\.[^\.]*$'

How to put all theses into one line?

  • [^\.] matches on collating elements other than . and backslash, is it really what you want? I suspect you want to match on lines that contain one and only one dot instead. – Stéphane Chazelas Aug 17 at 10:01
  • I want one dot only. Example: gmail.com, google.com. But [^\.] is to exclude literal dot but does not exclude the backslash. The backslash is used to express literal dot because it is a special character in reges (if I do not add \, the dot is interpreted as "any character". With backslash, it interpreted as dot). – user9371654 Aug 17 at 10:05
  • 1
    No . is always litteral inside brackets. If you add a backslash, then the backslash becomes part of the set as well. – Stéphane Chazelas Aug 17 at 10:06
  • 1
    Try it: ( echo 'backslash \'; echo 'dot .'; ) | grep -e '[.]' (or with grep '[\.]') – ilkkachu Aug 17 at 10:07
up vote 2 down vote accepted

You can't combine reverse and forward matches in one grep invocation

You can do it with sed:

sed -e '/^www\./d' -e '/\//d' -e '/^[^.]*\.[^.]*$/!d' ./*.txt

Or awk (which contrary to sed would be able to print the name of the matching file like grep):

awk -F. 'NF == 2 && !/^www\./ && !/\// {print FILENAME": "$0}' ./*.txt

You could do it with two grep invocations provided you don't want the file names to be printed:

cat ./*.txt | grep '^[^.]*\.[^.]*$' | grep -v -e / -e '^www\.'

Here using cat to feed the content of all the files on stdin so the first grep doesn't print the file names. Some grep implementations have grep -h to skip printing the file names if there's more than one file. In the case of only one file name, grep doesn't print the file name anyway, and you can feed it on its stdin with redirections:

<onefile.txt grep '^[^.]*\.[^.]*$' | grep -v -e / -e '^www\.'

You could implement negation with PCRE's (?!...) negative look-ahead operators if your grep supports -P:

grep '^(?!www\.)(?!.*/)[^.]*\.[^.]*$' ./*.txt

But here, you could do it all with -v with:

grep -v -e / -e '^www\.' -e '^[^.]*$' -e '\..*\.'

That is also exclude lines that contain no dot and lines that contain more than one dot.

  • Thanks. It looks a bit complex. If piping will work (not wrong) I will use it. The question is shall I use the file name in each command? i.e. grep -v -e '^www\.' -e '/' test2.txt | grep -e '^[^.]*\.[^.]*$' test2.txt > result.txt OR grep -v -e '^www\.' -e '/' test2.txt | grep -e '^[^\.]*\.[^\.]*$' > result.txt. I know I can test it but with toy examples it can not show exactly what will happen in the large file. I want to make sure as I'm not Linux familiar. – user9371654 Aug 17 at 10:15
  • @user9371654, see edit. – Stéphane Chazelas Aug 17 at 10:23
  • Thanks. I would go with: cat ./*.txt | grep '^[^.]*\.[^.]*$' | grep -ve / -ve '^www\.' But Ihave two questions: can I eliminate the cat? i.e. using the file name after the first grep command which includes the file name: grep '^[^.]*\.[^.]*$' myfile.txt then in the next command after the piping | I do not use the file name? – user9371654 Aug 17 at 10:26
  • @user9371654, you want the second grep to grep the output of the first grep, not of the file. My answer covers how to eliminate the cat (in the case of only one file, or with the non-standard -h for more than one file). – Stéphane Chazelas Aug 17 at 10:29
  • <onefile.txt grep '^[^.]*\.[^.]*$' | grep -v -e / -e '^www\.' provides similar result to: grep '^[^.]*\.[^.]*$' onefile.txt | grep -v -e / -e '^www\.' ?? or are there differences? – user9371654 Aug 17 at 11:24

Pipe the first grep's result into the second grep.

  • 1
    Can you provide the command please? – user9371654 Aug 17 at 10:06

Your Answer

 

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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