1

Why is it that when I pipe svn diff output to, say less, I get a bunch of ESC characters?

$ svn diff | less

Index: test/unit/tour_guide_tip_test.rb
===================================================================
ESC[1;31m--- test/unit/tour_guide_tip_test.rb   (revision 0)ESC[0;0m
ESC[1;34m+++ test/unit/tour_guide_tip_test.rb   (revision 66)ESC[0;0m
ESC[1;35m@@ -0,0 +1,7 @@ESC[0;0m
ESC[1;34m+require 'test_helper'ESC[0;0m
ESC[1;34m+ESC[0;0m
ESC[1;34m+class TourGuideTipTest < ActiveSupport::TestCaseESC[0;0m
ESC[1;34m+  # test "the truth" doESC[0;0m
ESC[1;34m+  #   assert trueESC[0;0m
ESC[1;34m+  # endESC[0;0m
ESC[1;34m+endESC[0;0m

However, if I direct output to a file (svn diff > whatever.diff) and then less whatever.diff it looks fine?

$ svn diff > whatever.diff
$ less whatever.diff

Index: test/unit/tour_guide_tip_test.rb
===================================================================
--- test/unit/tour_guide_tip_test.rb    (revision 0)
+++ test/unit/tour_guide_tip_test.rb    (revision 66)
@@ -0,0 +1,7 @@
+require 'test_helper'
+
+class TourGuideTipTest < ActiveSupport::TestCase
+  # test "the truth" do
+  #   assert true
+  # end
+end
André Dion
  • 113
  • 4
  • @Tim: Good point. @André: Please try to use `less -R` if this is available on OSX. This does pass the "raw control characters" to the terminal. – mpy Sep 10 '13 at 14:14

1 Answers1

2

These escape characters mark parts of the output that are colored if they are not piped.

Based on this very similar question and its answer I suggest you try to use less -R instead of plain less.

If you want to use other tools than just less, you could strip the sequences with sed 's/\x1b\[[0-9]*m//g' as discussed in this answer.

Your complete command would then be

svn diff | sed 's/\x1b\[[0-9]*m//g' | othertool

In OS X escape codes are different so the pattern must be changed. It also seems to be the case that (using OS X) the escape sequence \x1b will work with perl but not with sed. A resulting expression that works for both linux and OS X is then:

svn diff | perl -pe "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[mK]//g" | othertool
Tim
  • 2,132
  • 1
  • 22
  • 27
  • That's great. What if I wanted to use another program that doesn't have an option like `less -R`, such as [Sublime](http://www.sublimetext.com/) (`svn diff | subl`)? Is there a way to tell `svn diff` itself to strip colors? – André Dion Sep 10 '13 at 15:09
  • @AndréDion I updated the answer. – Tim Sep 10 '13 at 15:30
  • OS X does indeed include `sed`. Unfortunately this didn't seem to work—I still have escape characters. If you notice, the escape sequence in the snippet I pasted includes a `;` where in [the thread you linked to](http://superuser.com/questions/380772/removing-ansi-color-codes-from-text-stream) there are no semi-colons. I think the regex simply needs to be updated to account for it. The escape character is also different. – André Dion Sep 10 '13 at 17:40
  • @AndréDion Okay, when I tested it on my linux system it worked. But from your question it seems that the codes are different on OSX. This means the `sed` pattern must be changed. Try `sed 's/\x1b\[[01];[0-9]*m//g'`. – Tim Sep 11 '13 at 08:15
  • @AndréDion I added two solutions that I googled. Please report if they work, because I cannot test them. – Tim Sep 11 '13 at 08:41
  • `perl -pe "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[mK]//g"` did the trick! Thanks for all your help, Tim. – André Dion Sep 11 '13 at 11:34
  • Since it's unlikely I'll commit that pattern to memory, I've created a convenient alias (`alias killesc='perl -pe "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[mK]//g"'`) to use, e.g., `svn di | killesc | subl &` – André Dion Sep 11 '13 at 11:40