0

I have a program writing text outputs to STDOUT. I would like to filter and color these outputs. In PowerShell, I wrote a CmdLet, which parses text lines and emits them to the console and colors certain parts if needed. Example

In PowerShell I have such a function:

function Write-ColoredProgLine
{ [CmdletBinding()]
  param(
    [Parameter(ValueFromPipeline=$true)]
    $InputObject,

    [Parameter(Position=1)]
    [switch]$SuppressWarnings = $false,
    [Parameter(Position=2)]
    [string]$Indent = ""
  )

  begin
  { $ErrorRecordFound = $false  }

  process
  { if (-not $InputObject)
    { Write-Host "Empty pipeline!"  }
    elseif ($InputObject -is [string])
    { if ($InputObject.StartsWith("vlib "))
      { Write-Host "${Indent}$InputObject" -ForegroundColor Gray   }  }
      elseif ($InputObject.StartsWith("** Warning:") -and -not $SuppressWarnings)
      { Write-Host "${Indent}WARNING: " -NoNewline -ForegroundColor Yellow
        Write-Host $InputObject.Substring(12)
      }
      elseif ($InputObject.StartsWith("** Error:") -and -not $SuppressWarnings)
      { $ErrorRecordFound += 1
        Write-Host "${Indent}WARNING: " -NoNewline -ForegroundColor Yellow
        Write-Host $InputObject.Substring(12)
      }
    }
    else
    { Write-Host "Unsupported object in pipeline stream"   }
  }

  end
  { $ErrorRecordFound   }
}

Usage:

$expr = "prog.exe -flag -param foo"
$errors = Invoke-Expression $expr | Write-ColoredProgLine $false "  "

How can I process such operations in Bash?

I need some kind of inner state in the filter script, so tools like GRC are not powerful enough.

Paebbels
  • 15,573
  • 13
  • 70
  • 139
  • Bash for windows, I assume? Entirely for entertainment as well? – Austin T French Nov 10 '16 at 23:25
  • Bash for Linux (Debian). Not for entertainment :). I need to support both platforms :). – Paebbels Nov 10 '16 at 23:26
  • Ah, so this is a question on porting to bash, gotcha! – Austin T French Nov 10 '16 at 23:27
  • 1
    PowerShell 6 runs on Linux. It is an open source project. While not ready for production, have you tried it? https://github.com/PowerShell/PowerShell – lit Nov 11 '16 at 13:34
  • Wow!!!. When did that happen? Last time I looked for PowerShell on Linux I found an old and outdated project with only a handful of CmdLets translating to standard Linux programs like `ps` pr `ls`. I'll definitively test it! – Paebbels Nov 11 '16 at 19:02

2 Answers2

2

Here is a POSIX compatible way to do that:

awk '
/vlib/ {
  $0 = "\33[1;36m" $0 "\33[m"
}
/warning/ {
  $0 = "\33[1;33m" $0 "\33[m"
}
1
'

Result:

console screenshot

It should be noted that you cannot use POSIX Sed for this. While it is tempting, POSIX Sed has no way to create the escape sequences needed here, while POSIX Awk does.

Zombo
  • 1
  • 62
  • 391
  • 407
0

You could use sed in your pipeline. Maybe it's not the easiest tool but very powerful. You can do pretty much with a substitution command:

echo test | sed -e 's/es/ES/'

output:

tESt

this could be used also for removing some patterns by substitution with nothing:

sed -e 's/pattern//'

and adding prefixes/suffixes to your patterns (& is your match):

sed -e 's/pattern/PREFIX&SUFFIX/'

For coloring syntax check this link: http://ascii-table.com/ansi-escape-sequences.php

But if you need keeping some inner state it will be easier to use awk

woockashek
  • 1,588
  • 10
  • 25
  • `sed` has no state. I need a state machine in the script to process chains of different text lines with markers. So there are begin markers, text, highlight markers, text and finally end markers. – Paebbels Nov 11 '16 at 01:23
  • Could I read from STDIN and write to STDOUT in a while loop and exit on EOF? – Paebbels Nov 11 '16 at 01:24
  • reading from stdin in bash scripts: http://stackoverflow.com/q/6980090/3722896, to write on standard output you can just use `echo` – woockashek Nov 11 '16 at 12:11