loftybloke
loftybloke

Reputation: 23

powershell append to output

I'm 'teaching myself to powershell' and have come a cropper already, and google/this site hasn't enabled me to find a solution. I'm compiling a text file with filelists from different directories, but i'm having trouble appemnding new data to the file.

get-childitem $dir -recurse | % {write-output $_.fullname} >$file

creates my file, but then i want to APPEND new records from the below

get-childitem $dir2 -recurse | % {write-output $_.fullname} >$file

I've tried both add-content and -append, but I cant figure out what I'm not doing to get it right.

Upvotes: 2

Views: 17007

Answers (3)

ScriptAutomate
ScriptAutomate

Reputation: 1080

Short Answer

The pipeline used here can be eliminated, and usage of Out-File would make life easy:

Out-File (Get-ChildItem $dir -Recurse).FullName -FilePath $File

To append would be to simply use the -Append flag:

Out-File (Get-ChildItem $dir2 -Recurse).FullName -FilePath $File -Append

Note: This only works in PowerShell v3 and up, as PowerShell v2 relied on the pipeline to expand properties of objects within an array. In that case, the best route is to use something more like @david-martin proposed on this same thread.

Long Answer, and Best Practices

In a different thread, Script to Append The File, they were having similar difficulties with appending files. Though, they were also using the pipeline in a way that was unnecessary (more so than you have used in your example).

Their pipeline usage looked like this:

$PathArray | % {$_} | Out-File "C:\SearchString\Output.txt"

Now, again, Out-File has an -Append parameter. Simply modifying their code to have it tagged on at the end took care of things.

Though, their ForEach-Object statement (the % symbol) is pretty useless in the pipeline and isn't needed (very close in similarity to how yours is used). This is because you are only using the ForEach-Object loop to output the object without any modification. This is exactly what the pipeline does by default, which is pass each object along to the next command.

For more information on the pipeline: About Pipelines

If Update-Help has been run locally, one can use Get-Help to locally run Get-Help about_pipelines to see information too.

Instead of this:

$PathArray | % {$_} | Out-File "C:\SearchString\Output.txt" -Append

We could do this:

$PathArray | Out-File "C:\SearchString\Output.txt" -Append

[Recommended] That example can also eliminate the need for the pipeline all together, as using a pipeline is less efficient if it can be done without it. Doing everything one can possibly do without the pipeline, or to the left of each pipe in the pipeline, is to "filter left" (see the following article for more about why one should filter left, format right: Filtering Command Output in PowerShell):

Out-File -InputObject $PathArray -FilePath "C:\SearchString\Output.txt" -Append

Note: In the case above, -Append is only needed if the file already exists and is being extended.

Remember: Get-Help, and Read The Friendly Manual (RTFM)

The easiest way to troubleshoot is to checkout help documentation. Use Get-Help to checkup whatever you need: parameter sets, available parameters, examples, etc. Make sure to run Update-Help in order to have detailed documentation available locally. To checkout everything:

Update-Help    
Get-Help Out-File -Full

For more detailed information that is good to know about data stream/output redirection:

  • PowerShell redirection operators, such as > and >> (but also redirection of data streams with n> and n>&1), and the available streams per PowerShell version: About Redirection in PowerShell (or: Get-Help about_redirection in PowerShell)
  • Tee-Object cmdlet), a cmdlet that acts as a more robust version of Out-File (or: Get-Help tee-object in powerShell)

Upvotes: 1

Ignotus
Ignotus

Reputation: 301

Try:

get-childitem $dir -recurse | % {write-output $_.fullname} >> $file

(Tested and works)

The double >> makes it append always, a single > overwrites each time.

Or change your syntax to use Out-File

get-childitem $dir -recurse | % {write-output $_.fullname} | out-file -filepath $file -Append

(untested)

In this case the variable $file must hold the full path. Like: C:\directory\filename.txt

Upvotes: 7

David Martin
David Martin

Reputation: 12248

You can use Out-File to write to a file, adding the append parameter will append to the file.

Get-ChildItem $dir -recurse | Select-object -ExpandProperty Fullname | Out-File -FilePath $file
Get-ChildItem $dir2 -recurse | Select-object -ExpandProperty Fullname | Out-File -FilePath $file -Append

Upvotes: 1

Related Questions