diff --git a/README.md b/README.md
index 1ef34947..e35d61a2 100644
--- a/README.md
+++ b/README.md
@@ -217,7 +217,7 @@ Usage:
   golangci-lint run [flags]
 
 Flags:
-      --out-format string           Format of output: colored-line-number|line-number|json (default "colored-line-number")
+      --out-format string           Format of output: colored-line-number|line-number|json|tab (default "colored-line-number")
       --print-issued-lines          Print lines of code with issue (default true)
       --print-linter-name           Print linter name in issue line (default true)
       --issues-exit-code int        Exit code when issues were found (default 1)
@@ -236,7 +236,7 @@ Flags:
   -e, --exclude strings             Exclude issue by regexp
       --exclude-use-default         Use or not use default excludes:
                                       # errcheck: Almost all programs ignore errors on these functions and in most cases it's ok
-                                      - Error return value of .((os\.)?std(out|err)\..*|.*Close|os\.Remove(All)?|.*printf?|os\.(Un)?Setenv). is not checked
+                                      - Error return value of .((os\.)?std(out|err)\..*|.*Close|.*Flush|os\.Remove(All)?|.*printf?|os\.(Un)?Setenv). is not checked
                                     
                                       # golint: Annoying issue about not having a comment. The rare codebase has such comments
                                       - (should have comment|comment on exported method|should have a package comment)
diff --git a/pkg/commands/run.go b/pkg/commands/run.go
index a5ec9cb7..65762265 100644
--- a/pkg/commands/run.go
+++ b/pkg/commands/run.go
@@ -235,12 +235,19 @@ func (e *Executor) runAndPrint(ctx context.Context, args []string) error {
 	}
 
 	var p printers.Printer
-	if e.cfg.Output.Format == config.OutFormatJSON {
+	format := e.cfg.Output.Format
+	switch format {
+	case config.OutFormatJSON:
 		p = printers.NewJSON()
-	} else {
+	case config.OutFormatColoredLineNumber, config.OutFormatLineNumber:
 		p = printers.NewText(e.cfg.Output.PrintIssuedLine,
-			e.cfg.Output.Format == config.OutFormatColoredLineNumber, e.cfg.Output.PrintLinterName)
+			format == config.OutFormatColoredLineNumber, e.cfg.Output.PrintLinterName)
+	case config.OutFormatTab:
+		p = printers.NewTab(e.cfg.Output.PrintLinterName)
+	default:
+		return fmt.Errorf("unknown output format %s", format)
 	}
+
 	gotAnyIssues, err := p.Print(ctx, issues)
 	if err != nil {
 		return fmt.Errorf("can't print %d issues: %s", len(issues), err)
@@ -296,6 +303,7 @@ func (e *Executor) parseConfig() {
 	e.initFlagSet(fs)
 	e.initRootFlagSet(fs)
 
+	fs.Usage = func() {} // otherwise help text will be printed twice
 	if err := fs.Parse(os.Args); err != nil {
 		if err == pflag.ErrHelp {
 			return
diff --git a/pkg/config/config.go b/pkg/config/config.go
index 08654ecd..17915080 100644
--- a/pkg/config/config.go
+++ b/pkg/config/config.go
@@ -10,9 +10,10 @@ const (
 	OutFormatJSON              = "json"
 	OutFormatLineNumber        = "line-number"
 	OutFormatColoredLineNumber = "colored-line-number"
+	OutFormatTab               = "tab"
 )
 
-var OutFormats = []string{OutFormatColoredLineNumber, OutFormatLineNumber, OutFormatJSON}
+var OutFormats = []string{OutFormatColoredLineNumber, OutFormatLineNumber, OutFormatJSON, OutFormatTab}
 
 type ExcludePattern struct {
 	Pattern string
@@ -22,7 +23,7 @@ type ExcludePattern struct {
 
 var DefaultExcludePatterns = []ExcludePattern{
 	{
-		Pattern: "Error return value of .((os\\.)?std(out|err)\\..*|.*Close|os\\.Remove(All)?|.*printf?|os\\.(Un)?Setenv). is not checked",
+		Pattern: "Error return value of .((os\\.)?std(out|err)\\..*|.*Close|.*Flush|os\\.Remove(All)?|.*printf?|os\\.(Un)?Setenv). is not checked",
 		Linter:  "errcheck",
 		Why:     "Almost all programs ignore errors on these functions and in most cases it's ok",
 	},
diff --git a/pkg/printers/tab.go b/pkg/printers/tab.go
new file mode 100644
index 00000000..c677d480
--- /dev/null
+++ b/pkg/printers/tab.go
@@ -0,0 +1,64 @@
+package printers
+
+import (
+	"context"
+	"fmt"
+	"io"
+	"text/tabwriter"
+
+	"github.com/fatih/color"
+	"github.com/golangci/golangci-lint/pkg/result"
+	"github.com/sirupsen/logrus"
+)
+
+type Tab struct {
+	printLinterName bool
+}
+
+func NewTab(printLinterName bool) *Tab {
+	return &Tab{
+		printLinterName: printLinterName,
+	}
+}
+
+func (p Tab) SprintfColored(ca color.Attribute, format string, args ...interface{}) string {
+	c := color.New(ca)
+	return c.Sprintf(format, args...)
+}
+
+func (p *Tab) Print(ctx context.Context, issues <-chan result.Issue) (bool, error) {
+	w := tabwriter.NewWriter(StdOut, 0, 0, 2, ' ', 0)
+
+	issuesN := 0
+	for i := range issues {
+		issuesN++
+		p.printIssue(&i, w)
+	}
+
+	if issuesN != 0 {
+		logrus.Infof("Found %d issues", issuesN)
+	} else if ctx.Err() == nil { // don't print "congrats" if timeouted
+		outStr := p.SprintfColored(color.FgGreen, "Congrats! No issues were found.")
+		fmt.Fprintln(StdOut, outStr)
+	}
+
+	if err := w.Flush(); err != nil {
+		logrus.Warnf("Can't flush tab writer: %s", err)
+	}
+
+	return issuesN != 0, nil
+}
+
+func (p Tab) printIssue(i *result.Issue, w io.Writer) {
+	text := p.SprintfColored(color.FgRed, "%s", i.Text)
+	if p.printLinterName {
+		text = fmt.Sprintf("%s\t%s", i.FromLinter, text)
+	}
+
+	pos := p.SprintfColored(color.Bold, "%s:%d", i.FilePath(), i.Line())
+	if i.Pos.Column != 0 {
+		pos += fmt.Sprintf(":%d", i.Pos.Column)
+	}
+
+	fmt.Fprintf(w, "%s\t%s\n", pos, text)
+}