Cheetah
Cheetah

Reputation: 14419

Powershell tail multiple files command

I can tail one file via the following command:

Get-Content -Path C:\log1.txt -Tail 10 –Wait

How do I extend this to multiple files, I have tried the following with no luck:

Get-Content -Path C:\log1.txt,C:\log2.txt -Tail 10 –Wait

This will only pick up updates from the first file, not the second.

Upvotes: 12

Views: 5366

Answers (4)

Chad Baldwin
Chad Baldwin

Reputation: 2602

I can't speak to how efficient this is, but since I'm using PowerShell Core 7.1.3, I can't use Workflows or ForEach -Parallel, but I can use ForEach-Object -Parallel, so I tried it just to see what would happen...

Get-ChildItem -Path C:\ -Filter log*.txt |
    ForEach-Object -Parallel {
        Get-Content -Wait -Tail 10 -Path $_
    } -ThrottleLimit 30

In my case, I had 27 files I needed to monitor, so I chose a number just above that, and this seemed to work.

Just to be sure it was working, I used this, which will output the source file name before each line:

Get-ChildItem -Path C:\ -Filter log*.txt |
    ForEach-Object -Parallel {
        $file = $_;
        Get-Content -Wait -Tail 10 -Path $file |
            ForEach-Object { Write-Output "$($file.Name): ${_}" }
    } -ThrottleLimit 30

Upvotes: 3

kym
kym

Reputation: 1203

Incorporating @McLeopold's comment into @Cheetah's code

function Tail (
  [Parameter(Mandatory=$true)][string[]]$Files,
  [long]$Tail = 1
) {
  workflow TailWorkflow (
    [string[]]$Files,
    [long]$Tail
  ) {
    foreach -parallel ($File in $Files) {
      Get-Content -Tail $Tail $File -Wait
    }
  }

  $ProgressPreference='SilentlyContinue'
  TailWorkflow -Files $Files -Tail $Tail
}

Upvotes: 0

crowne
crowne

Reputation: 8534

I needed tailed output across multiple files and I wanted to try do it in one line,
here's what I eventually came up with:

gci *.txt -recurse | ForEach-Object  { Write-Output "$_`n" + $(Get-Content $_ -tail 5) + "`n" }

Its takes a recursive directory listing of all files named *.txt,
writes the file path to console,
then writes the last 5 lines to console.

I didn't need to follow the tails of the files, they weren't being actively written to.

Upvotes: 0

Cheetah
Cheetah

Reputation: 14419

Based on @mjolinor's comment, I have come up with the following that appears to work,

Workflow My-Tail
{
    Param([string[]] $Path)

    foreach -parallel ($file in $path)
    {
        Get-Content -Path $file -Tail 1 -Wait
    }
}

My-Tail (dir C:\*.log -Include log1.txt,log2.txt)

However, this has some sort of progress bar that appears...

Upvotes: 13

Related Questions