Normally diff and git diff show both the original and the modified line with - and + respectively. Is there any way, I can filter only to see the modified line? This would reduce the number of lines to read by a factor of 2 instantly.

I was assuming

git diff test.yml | grep '^+' | less -R


git diff test.yml | egrep '^+' | less -R

to have the same result. ie they would show any new additions in a file. However egrep shows me the entire file. Why is that so?

With the above method anyways, I lose the color. Is there any way to retain the color?

  • So you don't care whether it's a new line or a replaced line?
    – Philippos
    Commented Sep 14, 2017 at 11:40

6 Answers 6


You can use --word-diff to condense the + and - lines together with the changes highlighted using red/green text and stop using grep all together.

enter image description here

You can combine this with -U0 to remove all context around the diffs if you really want to condense it down further.

enter image description here

This approch is better than using grep as you don't lose output, you can tell when a line was added or simply changed and you don't completely lose removals while still condensing the output down into something that is easy to read.

The answer to the question regarding egrep is already answered by @Stephen Kitt here

  • word-diff and U# is indeed cool ! It immediately reduces the length of the diff by a factor of 2 making it read quicker. If you cite the answers form @Stephen Kitt with respect to egrep, I will mark it as accepted. Commented Sep 14, 2017 at 14:05
  • 1
    Your syntax highlighting is really impressive, but next time please use copy-paste...
    – peterh
    Commented Sep 15, 2017 at 19:20
  • Problem with copy paste in this example is it loses all of the syntax highlighting which is important to show the actual diff - otherwise it makes no sense. Commented Sep 15, 2017 at 22:34
  • 1
    This helped OP but it doesn't actually answer the question in the title. If you have a million deletions and two additions, this answer will improve the diff from 1,000,004 lines to 1,000,002, rather than the 2 lines that I'm trying to get. Commented Apr 24 at 20:12

egrep uses extended regular expressions, so

egrep '^+'

matches one or more beginnings of lines (+ is a special character here), which is undefined and can result in an error or a variety of behaviours depending on the egrep implementation.

To match the “+” character you need to escape it:

egrep '^\+'

To see colours, you need to force git to output them; by default it disables them when piping:

git diff --color

To filter this you need to take the escape codes used for colours into account:

git diff --color ... | egrep '^.[[[:digit:]]+m\+' | less -R
  • I get egrep: repetition-operator operand invalid with macOS version of grep and zsh. egrep "^\+" worked for me Commented Aug 24, 2022 at 5:00
  • ^ is used for history when at the start of the line like in csh, ^ is also an extendedglob operator, but here, their error is from egrep. grep -E '^+' produces undefined results in the POSIX specification, some grep implementations treat it as an error, some as one or more of nothing at the beginning of the line, some could try and interpret it as one or more beginning of the subject, whatever that means, or as + at the beginning of the subject... Commented Aug 26, 2022 at 14:41
  • Ah yes of course, since the error starts with egrep: anyway it has to come from egrep Commented Aug 26, 2022 at 14:50
  • See also egrep '^[+]' as an alternative way to escape the +. Commented Aug 26, 2022 at 15:04

Can also be done with grep alone.

$ grep -xvFf filea.txt fileb.txt

This takes the lines from one file and looks for them in the other, printing out only ones which don't match exactly.


While using grep works, you can use a flag to achieve similar and possibly a more succinct result.

git diff

You can adjust the amount of context git diff provides with the -U flag. From man git-diff:

   -U<n>, --unified=<n>
       Generate diffs with <n> lines of context instead of the usual three. Implies -p.

git diff -U0 will produce minimal/simple output with no context for each change.


The same flag applies to diff:

   -u  -U NUM  --unified[=NUM]
          Output NUM (default 3) lines of unified context.

Example (diff -U0 would work the same way):

$ diff -U0 <(echo -e "abc123\ndef345") <(echo -e "abc123\nghi678")
--- /dev/fd/63  2017-09-14 09:18:01.000000000 -0400
+++ /dev/fd/62  2017-09-14 09:18:01.000000000 -0400
@@ -2 +2 @@

However egrep shows me the entire file. Why is that so?

Because egrep uses extended regular expressions, so egrep ^+ matches the beginning of each line one or more times (i.e. it matches all lines). Use egrep ^\+ to match only lines starting with +.

With the above method anyways, I lose the color. Is there any way to retain the color?

Yes, add option --color=always:

git diff --color=always | less -R

The following shows a git diff only showing modified lines while preserving color.

git diff file1.txt file2.txt --word-diff --color=always | grep -P '\+|\-' --color=never

You must log in to answer this question.

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