ChatGPT解决这个技术问题 Extra ChatGPT

使用 PowerShell 遍历目录中的文件

如何更改以下代码以查看目录中的所有 .log 文件,而不仅仅是一个文件?

我需要遍历所有文件并删除所有不包含“step4”或“step9”的行。目前这将创建一个新文件,但我不确定如何在此处使用 for each 循环(新手)。

实际文件的名称如下:2013 09 03 00_01_29.log。我希望输出文件要么覆盖它们,要么具有相同的名称,并附加“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

V
Vincent G

试试这个:

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')
}

谢谢。 BaseName 部分不起作用(版本 1) - 但我通过首先创建完整文件的备份然后对原始文件进行更改来管理。
对于 v1,您可以使用以下内容提取基本名称:[io.path]::GetFileNameWithoutExtension($name)
如果我用 FullName 替换 BaseName,我会得到我想要的。
P
PVitt

要获取目录的内容,您可以使用

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

然后你也可以循环这个变量:

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
}

一个更简单的方法是 foreach 循环(感谢@Soapy 和@MarkSchultheiss):

foreach ($f in $files){
    $outfile = $f.FullName + "out" 
    Get-Content $f.FullName | Where-Object { ($_ -match 'step4' -or $_ -match 'step9') } | Set-Content $outfile
}

这将创建一个名为“out.log”的输出文件。如何为每个输入文件创建单独的输出文件?
@user2725402 我添加了一个名为 out 的输入依赖输出文件
好的 2 个新问题...由于某种原因,现在这与匹配相反,即它创建的文件仅包含不包含“step4”或“step9”的记录。此外,它使用“out”作为扩展名进行重命名,因此文件被命名为“XXX.log.out” - 我尝试使用 BaseName 但无法正确使用。
你也可以做foreach ($f in Get-ChildItem "C:\Users\gerhardl\Documents\My Received Files\") { ... }
或使用 ForEach ($f in $files){...}
S
Sarath Subramanian

如果您需要在目录中递归循环以查找特定类型的文件,请使用以下命令,该命令会过滤 doc 文件类型的所有文件

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

如果您需要对多种类型进行过滤,请使用以下命令。

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

现在,$fileNames 变量充当 数组,您可以从中循环并应用您的业务逻辑。


让我烦恼的是隐藏和/或系统文件的遗漏。要同时查看它们,您必须使用 Get-ChildItem 的 -Force 参数。请参阅 docs.microsoft.com/en-us/powershell/module/… 处的文档。
u
user1628658

其他答案很好,我只想添加......在 PowerShell 中可用的不同方法:安装 GNUWin32 实用程序并使用 grep 查看行/将输出重定向到文件 http://gnuwin32.sourceforge.net/

这每次都会覆盖新文件:

grep "step[49]" logIn.log > logOut.log 

这会附加日志输出,以防您覆盖 logIn 文件并希望保留数据:

grep "step[49]" logIn.log >> logOut.log 

注意:为了能够在全局范围内使用 GNUWin32 实用程序,您必须将 bin 文件夹添加到系统路径中。


这个问题被标记为 PowerShell,而不是 Unix
是的。明显地。我的看法相当简单:您可以在 Windows 中使用 GNUWin32 实用程序,因此您可以在 Powershell 中轻松使用 *nix 工具。作品。从来没有人说过,答案必须完全来自 Powershell。即使他们这样做了,您仍然可以直接从 Powershell 调用 Win32 Utils。 AFAIK 使用任何可用且兼容的东西实际上并不是一件坏事。
我会编辑我之前的评论,但我超过了 5 分钟的限制: SteveC:你是说合并在 Windows 下可以正常工作的 GNU 工具在某种程度上违反了 Powershell?那是一回事。我知道纯粹在 Powershell 中解决这个问题可能在短期内更有成效。从长远来看,扩大可能性实际上具有更多优点。您添加了更多选项,并且完全在 Windows 和 Powershell 中工作,没有任何像 Cygwin 这样的 Linux 模拟器。所以虽然我理解你的保留,但我不同意。
问题是关于在 PowerShell 中查找,而不是可以使用的多种其他语言。
答案是针对问题的。这个问题很明确,因为它需要 PowerShell 中的答案。您的答案是安装并使用它。您可以建议安装 Ruby 等。