351

How can I change the following code to look at all the .log files in the directory and not just the one file?

I need to loop through all the files and delete all lines that do not contain "step4" or "step9". Currently this will create a new file, but I'm not sure how to use the for each loop here (newbie).

The actual files are named like this: 2013 09 03 00_01_29.log. I'd like the output files to either overwrite them, or to have the SAME name, appended with "out".

$In = "C:\Users\gerhardl\Documents\My Received Files\Test_In.log"
$Out = "C:\Users\gerhardl\Documents\My Received Files\Test_Out.log"
$Files = "C:\Users\gerhardl\Documents\My Received Files\"

Get-Content $In | Where-Object {$_ -match 'step4' -or $_ -match 'step9'} | `
Set-Content $Out

3 Answers 3

509

Give this a try:

Get-ChildItem "C:\Users\gerhardl\Documents\My Received Files" -Filter *.log | 
Foreach-Object {
    $content = Get-Content $_.FullName

    #filter and save content to the original file
    $content | Where-Object {$_ -match 'step[49]'} | Set-Content $_.FullName

    #filter and save content to a new file 
    $content | Where-Object {$_ -match 'step[49]'} | Set-Content ($_.BaseName + '_out.log')
}
3
  • thanks. The BaseName part does not work (version 1) - but I managed by first creating a backup of the full file then making the change to the original file. Commented Sep 17, 2013 at 12:25
  • 7
    For v1, you can use the following to extract the base name: [io.path]::GetFileNameWithoutExtension($name)
    – Shay Levy
    Commented Sep 17, 2013 at 12:26
  • 1
    If I replace BaseName with FullName I get what I want.
    – M--
    Commented Oct 31, 2018 at 13:57
145

To get the content of a directory you can use

$files = Get-ChildItem "C:\Users\gerhardl\Documents\My Received Files\"

Then you can loop over this variable as well:

for ($i=0; $i -lt $files.Count; $i++) {
    $outfile = $files[$i].FullName + "out" 
    Get-Content $files[$i].FullName | Where-Object { ($_ -match 'step4' -or $_ -match 'step9') } | Set-Content $outfile
}

An even easier way to put this is the foreach loop (thanks to @Soapy and @MarkSchultheiss):

foreach ($f in $files){
    $outfile = $f.FullName + "out" 
    Get-Content $f.FullName | Where-Object { ($_ -match 'step4' -or $_ -match 'step9') } | Set-Content $outfile
}
8
  • This creates one output file named "out.log". How can I create a separate output file for each input file? Commented Sep 17, 2013 at 10:31
  • @user2725402 I added an input dependend output file that is named <input file name>out
    – PVitt
    Commented Sep 17, 2013 at 10:39
  • 1
    okay 2 new issues... this now for some reason does the opposite of the match, i.e. it creates a file with only records NOT containing "step4" or "step9". Also, it is renaming using "out" as an extension, so files are named "XXX.log.out" - I tried using BaseName but can't get it right. Commented Sep 17, 2013 at 12:01
  • 4
    You can also do foreach ($f in Get-ChildItem "C:\Users\gerhardl\Documents\My Received Files\") { ... }
    – Soapy
    Commented Aug 19, 2015 at 12:55
  • 2
    or use ForEach ($f in $files){...} Commented May 31, 2018 at 13:37
47

If you need to loop inside a directory recursively for a particular kind of file, use the below command, which filters all the files of doc file type

$fileNames = Get-ChildItem -Path $scriptPath -Recurse -Include *.doc

If you need to do the filteration on multiple types, use the below command.

$fileNames = Get-ChildItem -Path $scriptPath -Recurse -Include *.doc,*.pdf

Now $fileNames variable act as an array from which you can loop and apply your business logic.

2
  • 5
    What bugged me was the omission of hidden and/or system files. To also see them you have to use the -Force parameter to Get-ChildItem. See its doc at learn.microsoft.com/en-us/powershell/module/… .
    – til_b
    Commented Feb 13, 2020 at 11:45
  • Note: The Include parameter only works when either the command includes the Recurse parameter or the path leads to the contents of a directory (stackoverflow.com/a/41700792) Commented Apr 27, 2023 at 18:23

Not the answer you're looking for? Browse other questions tagged or ask your own question.