19

I have a lot of lines in my LIST file and want to list only lines whose name does not start by (or contains) "git".

So far I have :

cat LIST | grep ^[^g]

but I would like something like :

#not starting by "git"
cat LIST | grep ^[^(git)]
#not containing "git"
cat LIST | grep .*[^(git)].*

but it is not correct. What regex should I use ?

5 Answers 5

26

Using grep in this case with -P option, which Interprets the PATTERN as a Perl regular expression

grep -P '^(?:(?!git).)*$' LIST

Regular expression explanation:

^             the beginning of the string
 (?:          group, but do not capture (0 or more times)
   (?!        look ahead to see if there is not:
     git      'git'
   )          end of look-ahead
   .          any character except \n
 )*           end of grouping
$             before an optional \n, and the end of the string

Using the find command

find . \! -iname "git*"
4
  • 1
    Not sure how/if the expression would be optimzed internally, but I wouldn't use the quantifier + on the outer group. Considering it won't capture its match I'd simply remove it alltogether for a more simple/readable expression.
    – Mario
    Oct 13, 2013 at 9:50
  • This expression will match anything from start to end of a line that does not start with git
    – hwnd
    Oct 13, 2013 at 14:27
  • Your first command is what I am looking for :) However I do not understand what (?!git) does ?
    – Vulpo
    Oct 13, 2013 at 16:28
  • It is a negative look ahead assertion, see updated edit.
    – hwnd
    Oct 13, 2013 at 16:33
18

Since the OP is looking for a general regex and not specially for grep, this is the general regex for lines not starting with "git".

^(?!git).*

Breakdown:

^ beginning of line

(?!git) not followed by 'git'

.* followed by 0 or more characters

7

If you want to simply list all lines that don't contain git try this

 cat LIST | grep -v git
3
  • In that specific case, it does work. Thanks. But I would have preferred the use of regular expressions since it can be used in much more cases (for exemple a perl script parsing a user input).
    – Vulpo
    Oct 8, 2013 at 11:15
  • Maybe this post on SO has what you need.
    – dinesh
    Oct 8, 2013 at 16:55
  • Almost. I try to match what does NOT contain the string. Without using "-v" option from grep if possible :)
    – Vulpo
    Oct 11, 2013 at 9:33
1

Slight modification to the accepted answer that will work in more situations and a broader swath of engines (moves . to outside second closing parenthesis):

^(?:(?!git)).*$

This example finds any lines that begin with anything except git or ls:

^(?:(?!git|ls)).*$
2
  • The non-capture group is useless. ^(?!git).*$ does the same.
    – Toto
    Jan 26, 2022 at 19:36
  • The non-capture group is not necessary, but it is useful. There is overhead in a capturing group, that can negatively impact performance: “The performance hit may be tiny, especially when working with small strings, but it's there.” Also, as Levithan describes, non-capturing groups conveniently do not clutter up backreferences and reduce maintenance burden, so developers do not have to worry about references.
    – rdela
    Jun 20, 2022 at 19:51
-2

If you wanna find the lines "not starting with git", you could also use:

^[^git].*
3
  • I don't quite understand the downvotes here. "^" inside cornered brackets e.g. [^not], simply means "not". I've tested this for Java Regex and it works!
    – blaucuk
    Jul 8, 2021 at 7:09
  • I do not think it is tested enough: your pattern will match everything that does not begin by "g", "i" OR "t". For example it will not match "iran" because it starts with "i". The question was to just ignore what began by "git".
    – Vulpo
    Aug 12, 2021 at 15:47
  • I see your point. I actually used it to filter out a single char at the end of the String .*[^s], but I didn't know multiple chars like above means "OR". Thanks for your input.
    – blaucuk
    Aug 13, 2021 at 16:16

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .