Powershell 脚本因文件锁定而失败

问题描述 投票:0回答:1

我有以下 PowerShell 脚本,我用它来移动包含特定字符串的目录中的所有文件:

gci -Path 'C:\Users\LG\Desktop\3039u\*.txt' -r|sls -Pattern '(?-i)^Engine:'|Move-Item -Destination "C:\Users\LG\Desktop"

但是,当尝试执行它时,我收到错误消息:

Move-Item : The process cannot access the file because it is being used by another process.
At line:1 char:77
+ ... -Pattern '(?-i)^Engine:'|Move-Item -Destination "C:\Users\LG\Desktop"
+                              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : WriteError: (C:\Users\LG\Des...Zeus ZEU-6T.txt:FileInfo) [Move-Item], IOException
    + FullyQualifiedErrorId : MoveFileInfoItemIOError,Microsoft.PowerShell.Commands.MoveItemCommand

对 sls 选择且 Move-Item 尝试移动的每个文件重复此操作。我已经使用 Process Explorer (Sysinternals) 验证没有其他进程使文件保持打开状态。这可能是命令编写不正确的问题,即 sls 在收集所有匹配文件的列表时保持文件打开,导致 Move-Item 无法访问它们?如果是这样,我应该如何重新格式化命令?

要明确的是 - 我希望它使用 sls 找到每个匹配的文件,然后将每个匹配移动到不同的文件夹。

问候

windows powershell locking
1个回答
0
投票

Select-String
sls
别名的目标)可能会在完成读取给定文件之前输出匹配项 - 解释为什么您无法移动该文件,因为
Select-String
仍然有一个打开的句柄。

您可以将操作分为 2 个管道,允许

Select-String
在开始移动文件之前完成搜索:

$FilesToMove = Get-ChildItem -Path 'C:\Users\LG\Desktop\3039u\*.txt' -Recurse |Select-String -Pattern '(?-i)^Engine:'

$FilesToMove |Move-Item -Destination "C:\Users\LG\Desktop"

然而,更有效的方法是一次仅针对 1 个文件调用

Select-String
- 这也允许您在获得第一个匹配项后立即停止
Select-String

Get-ChildItem -Path 'C:\Users\LG\Desktop\3039u\*.txt' -Recurse |ForEach-Object {
  $_ |Select-String -Pattern '(?-i)^Engine:' |Select-Object -First 1 |Move-Item -Destination "C:\Users\LG\Desktop"
}
© www.soinside.com 2019 - 2024. All rights reserved.