-1

I have a file called test.txtwith contents like below:

Si  28.086  Si.bhs
As   74.90000  As.pz-bhs.UPF

Here is some of my running of grep

enter image description here

I just can't understand, why grep bhs[^\.] test.txt won't grep the first line? Could someone please explain? Doesn't [^\.] represent any character other than dot?

user15964
  • 703
  • 2
  • 13
  • 27
  • Run `echo \.` and `echo [^\.]`. Quote your regexes. – muru Mar 06 '17 at 02:18
  • 1
    Is there actually a character after `bhs` on the first line? "followed by not dot" is not the same as "not followed by dot" – steeldriver Mar 06 '17 at 02:21
  • @steeldriver isn't there \n or \r after bhs? – user15964 Mar 06 '17 at 02:24
  • Hi, @muru. I don't get it. Neither `grep bhs[^\\.] test.txt` nor `grep 'bhs[^\\.] ' test.txt` works – user15964 Mar 06 '17 at 02:26
  • You could explicitly match the end-of-line using `grep 'bhs$'` or (if your `grep` supports PCRE mode) use `grep -P 'bhs(?!\.)'` – steeldriver Mar 06 '17 at 02:26
  • @steeldriver But the problem is that if you done it in notepad++ which also use PCRE, `bhs[^\.]` matches the first bhs – user15964 Mar 06 '17 at 02:28
  • @steeldriver Or you could try it here https://regex101.com/ – user15964 Mar 06 '17 at 02:29
  • @steeldriver However `grep -P 'bhs[^\\.]' test.txt` doesn't work – user15964 Mar 06 '17 at 02:30
  • 3
    `grep` searches within lines. The newline character (`\n`) is the _terminator_ of the line, so `[^.]` won't match it. Note that `[^\.]` is actually "any character except _backslash or dot_", as characters are not considered special within character classes – Fox Mar 06 '17 at 02:33
  • Hi, @Fox,"search within lines" makes sense, thank you. But why `[^\.]` also contains backslash? Isn't `\.` the escaping of dot? – user15964 Mar 06 '17 at 02:37
  • Nope. Test it: `printf 'bhs\\xyz\n' | grep 'bhs[^\.]'`. If your regexp is left unquoted, then your shell eats the backslash before `grep` gets it – Fox Mar 06 '17 at 02:40
  • @Fox Thank you very much. I now know `grep` and `grep -P` treat `[^\.]` differently – user15964 Mar 06 '17 at 02:59
  • @user15964 `grep 'bhs\.'` and `grep 'bhs[^.]'` – muru Mar 06 '17 at 05:27
  • Your image of text [isn't very helpful](//meta.unix.stackexchange.com/q/4086). It can't be copied into an editor, and it doesn't index very well, meaning that other users with the same problem are less likely to find the answer here. Please [edit] your post to incorporate the relevant text directly (preferably using copy+paste to avoid transcription errors). – Toby Speight Mar 06 '17 at 15:30

1 Answers1

0

You need to quote the regex, e.g

grep '[^.]' xxx

And you don't need to escape dot inside the brackets ..

daisy
  • 53,527
  • 78
  • 236
  • 383
  • Hi, daisy. Why I don't need to escape dot inside brackets? – user15964 Mar 06 '17 at 02:38
  • 1
    @user15964 Because "special characters" lose their special meaning within `[...]`. If you escape it, it will be interpreted as a backslash and a dot separately. – Kusalananda Mar 06 '17 at 07:44