grep, which, and tail commands?

Discussion in 'Scripting' started by Jon Miller, Jul 3, 2006.

  1. Jon Miller

    Jon Miller Guest


    I'm just starting to play around with PowerShell. It seems pretty cool.
    There are a few things that I'm wondering though. Namely, I'm wondering if
    there are equivalents for UNIX commands grep, which, and tail. With regard to
    grep, I'm wondering if there are plans for an updated version of FINDSTR.EXE
    that is possibly more robust. I've also found the UNIX which command very
    valuable. It tells you where in your path an executable file is found. And
    also, tail with the -f flag is very valuable for viewing log files and having
    their output displayed as new output is written to them. I've created my own
    ..NET implementations (in C#) of the later two commands, but, I was thinking
    it would be nice since there seems to be interest in finally getting a decent
    shell going for Windows that these other commands be bundled with the OS
    and/or the shell.

    Jon Miller, Jul 3, 2006
    1. Advertisements

  2. Jon Miller

    McKirahan Guest

    A Google found these links:

    GNU utilities for Win32

    UNIX Commands on Windows

    Unix commands in windows 1.0.0
    McKirahan, Jul 3, 2006
    1. Advertisements

  3. Jon,

    For grep equivalence take a look at get-content with a where-object in
    the second pipeline step.

    For example, you want to find lines in a file that match a regular
    expression pattern:

    get-content filename |
    where-object {$_ -match "regularExpressionPattern"}

    Adapt as necessary.

    For tail take a look at the -first and -last parameters on
    select-object. You would typically use it with a sort-object in the
    preceding pipeline step to order objects according to the criterion of

    I am not too familiar with "which" but from your description something

    get-childitem Script1.ps1 |
    format-list Name, PSParentPath

    should give you something similar to what you want.

    Andrew Watt MVP
    Author - Professional Windows PowerShell (Wrox)

    On Mon, 3 Jul 2006 14:37:01 -0700, Jon Miller <Jon
    Andrew Watt [MVP], Jul 4, 2006
  4. Thanks, but, the point is that I should not have to install 3rd party
    software to do this. IMHO, these are basic commands that should come
    standard with Windows.

    Jonathan Eric Miller, Jul 5, 2006
  5. Thanks for the response Andrew.

    Would it be easy to search multiple files and print the names/paths of the
    files that contain a match?
    I don't know if this would work because what "tail -f" does is monitor the
    file for changes. Everytime text is appended to the file, tail prints the
    new text out. I was able to implement this using FileSystemWatcher in .NET.
    Actually, I found that Get-Command seems to do exactly what UNIX which does.
    Basically, all you have to do is the following.

    PS C:\> get-command ping

    CommandType Name Definition
    ----------- ---- ----------
    Application ping.exe C:\WINDOWS\system32\ping.exe
    Jonathan Eric Miller, Jul 5, 2006
  6. Here you go. Adapt as necessary.

    It shows filenames which contain one or more matches and also shows
    the line which contains a match.

    $files = get-childitem [fr]*.txt
    foreach ($file in $files)
    if (get-content $file | where-object {$_ -match "red"})
    write-host "`n"
    write-host "$file" -ForegroundColor Yellow -Backgroundcolor Black
    $lines = get-content $file
    foreach ($line in $file)
    { get-content $file | where-object {$_ -match "red"}


    Andrew Watt MVP
    Andrew Watt [MVP], Jul 5, 2006
  7. Jon Miller

    Jon Miller Guest


    Jon Miller, Jul 5, 2006
  8. Jon Miller

    Jason Gurtz Guest

    ....tho the output is unnecessarily verbose and doesn't seem suitable for
    inclusion in a pipeline of commands.

    I guess a combination of grep \\ | awk "{print $3}" could alleviate
    that, but a -q flag would be better or better yet, quiet by default and
    have -v or -h for verbosity or human readable output.


    Jason Gurtz, Jul 6, 2006
  9. You mean like this ? :

    (get-command ping).Definition


    get-command ping | select definition
    get-command ping | ft definition

    Greetings /\/\o\/\/
    /\\/\\o\\/\\/, Jul 6, 2006
  10. Jon Miller

    Jason Gurtz Guest

    Oh, right on. The OO technique is even better! :)



    Jason Gurtz, Jul 6, 2006
  11. Jon Miller

    Jon Miller Guest

    Yeah, I think that's supposed to be one of the major differences between
    PowerShell and UNIX shells, namely, it uses objects and not just text
    Jon Miller, Jul 6, 2006
  12. I seem to be coming in the tail end of this thread for some reason. Has
    select-string been discussed? This is our grep equivalent. If you want to
    search through a directory of files, then you can do

    select-string pattern *.txt

    To search through a file heirarchy do

    dir -rec -include *.txt | select-string pattern


    Bruce Payette [MSFT]
    Windows PowerShell Technical Lead
    Microsoft Corporation
    This posting is provided "AS IS" with no warranties, and confers no rights.
    Bruce Payette [MSFT], Jul 6, 2006
  13. Jon Miller

    Jason Gurtz Guest

    I'm kinda interested if anyone could comment on the merits/differences
    of using select-string's -path arg with globing vs. get-childitem
    Esp. -rec offers a lot of power. Glad to say goodbye to du | grep | awk
    combos! A nice addition for PSH v2 might be a "maxDepth" value to the
    -recurse. I get this idea from Dan Cross' walk program written for
    Plan9 [1]


    Description (w/ C code):
    and Usage:
    Jason Gurtz, Jul 6, 2006
  14. Jon Miller

    Jon Miller Guest

    Cool, thanks Bruce. I'll try it out.

    On an unrelated note, I think I may have found a bug in get-command (not
    sure where I would report this). If you do the following, you will get back
    files that aren't executable but are in the path. For example, the following
    command returns C:\WINDOWS\system32\setup.bmp among others.

    gcm set*


    Jon Miller, Jul 6, 2006
  15. Interesting!

    I can confirm your finding. Also I see setup.txt displayed as an
    "application" too.

    Andrew Watt MVP
    Andrew Watt [MVP], Jul 7, 2006
  16. This is because all files in the path are found with command search and can
    be executed with the default file type handler. All of the following work as
    commands, launching setup.bmp in the default application handler:

    .. setup.bmp
    & setup.bmp

    This has several somewhat twisted but IMO useful side effects. For example:

    + You can make various external scripting tools work exactly as commands in
    PowerShell, even if the script suffix is not registered in %pathext%. This
    lets you make commands "unsearchable" in the command shell and explorer, yet
    still work fine in PS. The one limitation is that if the suffix is not in
    pathext, you must specify it as part of the command name; so you need to
    explicitly invoke setup.bmp

    In other ways this is annoying since it returns garbage, but you can filter
    that out by using the following pipeline element:

    .... | Where-Object { $env:pathext.Split(";") -contains $_.Extension}
    Alex K. Angelopoulos [MVP], Jul 7, 2006
  17. Jon Miller

    Jon Miller Guest

    While that makes sense, I don't know that that's actually the case because
    it found some *.tmp files on my system and I wouldn't think those a have a
    file association. If they do, that would be rather weird.

    Jon Miller, Jul 7, 2006
  18. Jon Miller

    Greg Borota Guest

    On my system I also get *.tmp files with get-command and they don't have
    any file association. I think this is an issue.

    "Jon Miller" wrote in message
    Greg Borota, Jul 7, 2006
  19. For tail, use the '-wait' parameter in Get-Content. It doesn't appear to be
    in the documentation, though :)

    Lee Holmes [MSFT]
    Windows PowerShell Development
    Microsoft Corporation
    This posting is provided "AS IS" with no warranties, and confers no rights.
    Lee Holmes [MSFT], Jul 12, 2006
  20. Jon Miller

    Jon Miller Guest

    Thanks Lee. That seems to work. However, there's one major problem. The
    files that I want to use this on are typically pretty large and I don't want
    to output the entire file before doing the wait.

    What I would like to do is only output say the last 10 lines of the file (or
    maybe none at all) and then do the wait. Is there a way to do that?

    Note, using Select-Object with -Last won't cut it because it seems to have
    to read the entire file and if the file is large that's highly inefficient.
    Plus, I'm not sure if that would work with -Wait.

    If this isn't implemented currently, but, could be added, it would be
    majorly helpful IMHO for watching log files such as those used by .NET trace


    Jon Miller, Jul 13, 2006
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.