Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I have the following Unix shell script. I would like to convert this into a Windows .bat file (I know I can use Cygwin instead of adapting it to a Windows environment. But Cygwin is not an option for me).

I know I can use Windows PowerShell reading material online. But I don't want to spend hours online learning from basics for this one time requirement. Please don't bash me for being lazy. I am sure this helps others as well by being a quick guide for someone searching online in the future.

Here is the script:

#!/bin/bash
echo ""
cat $1 | grep -A4 "Device_name"; echo ""
cat $1 | grep -A45 "Device_Oops"; echo ""
cat $1 | grep -A150 "Processes:" | sed '/Radar/q'; echo ""
cat $1 | grep -E '[0-9][0-9]:[0-9][0-9]:[0-9][0-9]' | grep -i -E 'error|restart' 

To answer questions on what I tried, I have trouble running the "find" command which is the equivalent of grep per this website http://tldp.org/LDP/abs/html/dosbatch.html

Here is my Joy.txt file (next two lines):

Device_name router@home
testing only

Then at the PowerShell prompt I ran the following command:

cat Joy.txt | find "Device_name"

I was expecting to see the first line in the above file. But instead I get the parameter format not correct error. Can someone help please?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
653 views
Welcome To Ask or Share your Answers For Others

1 Answer

A more or less direct equivalent of grep -A does not exist in findstr (or find), Windows' native grep equivalent. However, Select-String in PowerShell has this with the -Context parameter.

If I understand your script correctly, it means:

  • Write an empty line
  • Write all lines containing "Device_name", followed by four lines of context, followed by an empty line
  • Write all lines containing "Device_Oops", followed by 45 lines of context, followed by an empty line
  • Write all lines containing "Radar" if they either contain "Processes:" too or are within the first 150 lines following a line containing "Processes:"
  • Write all lines containing three pairs of digits, separated by a colon that also contain either "error" or "restart", case-insensitively.

So it more or less comes down to something like:

$f = Get-Content $args[0]
function Emulate-Grep {
    begin { $first = $true }
    process {
      if (!$first) { '--' }
      $_.Line
      $_.Context.PostContext
      $first = false
    }
}

Write-Host
$f | Select-String -CaseSensitive -Context 0,4 'Device_name' | Emulate-Grep; Write-Host
$f | Select-String -CaseSensitive -Context 0,45 'Device_Oops' | Emulate-Grep; Write-Host
[string[]]($f | Select-String -CaseSensitive -Context 0,150 'Processes:' | Emulate-Grep) -split "`n" -cmatch 'Radar'; Write-Host
$f -match 'd{2}(:d{2}){2}' -match 'error|restart'

(Untested)

Note that this is slightly ugly due to the attempt to emulate grep's output behaviour.

If you just need matching lines and the following, then I'd simply write a small function:

function Get-Matching([array]$InputObject, [string]$Pattern, [int]$Context = 0) {
    $n = $InputObject.Length - 1
    0..$n |
      where { $InputObject[$_] -cmatch $Pattern } |   
      foreach { $InputObject[$_..($_+$Context)] }
}

And then use it in a script that isn't so complex anymore (still trying to recreate some of your output choices, e.g. empty lines):

$f = gc $args[0]
Write-Host
Get-Matching $f Device_name 4; Write-Host
Get-Matching $f Device_Oops 45; Write-Host
Get-Matching $f 'Processes:' 150 | ? { $_ -cmatch 'Radar' }; Write-Host
Get-Matching $f 'd{2}(:d{2}){2}' | ? { $_ -match 'error|restart' }

You'll also notice that I got rid of Select-String, a cmdlet I never really understood the purpose of (except providing a close match of grep/findstr, but usually I find other means more flexible).


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...