使用batch或powershell在目录名称包含特定文本的一组目录中移动超过90天的文件

时间:2014-09-19 23:46:16

标签: windows powershell batch-file

我有一个服务器,其中有数百个子目录,可能包含扩展名为.flv且超过90天的文件。我需要找到这些文件,但只能在包含单词" ProdStream"的文件夹中找到。以他们的名义。

这样做的目的是将文件存档到AWS(我有一个工作脚本),文件的原始路径保存在日志中。

我可以使用forfiles找到所有子文件夹中的文件:

forfiles /P "SRC_PATH" /S /M *.flv /D -90 /C "cmd /C move @file "DEST_PATH""

但是,forfiles不允许我将文件夹名称用作变量。至少不是我尝试过的。所以我尝试使用for命令。

set stream=SRC_PATH
FOR /D /R %stream% %%X IN (ProdStream*) DO [something]

这是有效的,但只是部分原因,因为我无法在DO之后找到正确的命令来查找文件。

我还需要保存包含完整路径信息的文件列表。我一直在用这个:

forfiles /P "SRC_PATH" /S /M *.flv /D -90 /C "cmd /C echo @path @fsize" >MY_LOG_FILE

哪个有效,但不会过滤文件夹名称中的ProdStream文本。

我愿意在PowerShell和批处理中这样做。

我的PowerShell很弱,但它可以变得更强大!

想法?

服务器是Windows 2008 R2 Enterprise SP1

2 个答案:

答案 0 :(得分:1)

我希望不要拒绝你们,但是因为你愿意将此作为一种选择,我提出以下内容

$Path = "C:\temp"
$FolderFilter = "ProdStream"
$copyPath = "C:\archive"
$log = "c:\log"

Get-ChildItem -Path $Path -Recurse | Where-Object { ! $_.PSIsContainer -and $_.Extension -eq ".flv" -and $_.CreationTime -lt (Get-Date).Adddays(-90) -and ($_.FullName -split "\\")[-2] -match $FolderFilter } | ForEach-Object{
    Add-Content -Path $log "The following was archived $($_.FullName)"
    #Copy-Item -Path $_.FullName -Destination $copyPath 
}

好的,我会尝试尽我所能打破这个。

  1. 使用Get-ChildItem。它与cmd中的dir类似。在变量$ path搜索的起始路径中搜索所有文件和目录。我知道这不是你想要的,而是继续阅读
  2. Where-Object子句是匹配文件标准的神奇之处。我会打破条件

    • $_.PSIsContainer。我假设你有一个旧版本的powershell。这将返回所有文件而不是目录。
    • $_.Extension -eq ".flv"。你想要一个.flv说服文件。
    • $_.CreationTime -lt (Get-Date).AddDays(-90)。这将检查并查看文件的创建时间是否超过90天。
    • ($_.FullName -split "\\")[-2]。此条件将采用文件路径并将其转换为文件夹和文件的数组。获取该数组并返回第二个最后一项,该项目将是相关文件的文件夹名称。示例将是C:\temp\ProdStreamStuf\IMG_0571.JPG将返回ProdStreamStuf。获取父文件夹名称,看看它是否包含$FolderFilter,在我们的例子中是ProdStream。如果名称的一部分包含-matchtrue将返回ProdStream。此外,-match默认情况下不区分大小写。
  3. 如果满足上述条件的所有,则获取每个文件并通过ForEach-Object处理它们。 注意这可以直接传输到其他Powershell cmdlet,但我试图保持这个基本。

  4. 您提到要将找到的文件存储在日志中,因此请将文件的完整路径输出到Add-Content
  5. 的日志中
  6. 所有后,将文件复制到$copyPath指定的新家
  7. 将其保存到扩展名为.ps1的文件中,您可以双击它。
  8. 进行测试我在此行#上添加了评论Copy-Item -Path $_.FullName -Destination $copyPath,这将阻止其运行,您只需阅读$log即可查看将移动您想要的文件。然后,如果它正在工作,请删除#
  9. 注意 如果您通常不运行PowerShell脚本,则会出现ExecutionPolicy错误。如果是这种情况,您可以打开PowerShell会话并运行此Set-ExecutionPolicy remotesigned,这将允许计算机上的本地未签名脚本(如您刚刚制作的脚本),同时确保需要对来自Internet的脚本进行签名。您还需要更改所有$变量以匹配您需要的路径。此外,根据您拥有的文件和文件夹的数量,您可以重新排列条件。 PowerShell中的条件从左到右进行评估。如果一个是假的,它将不会评估其余的。所以你可以先放($_.FullName -split "\\")[-2] -match $FolderFilter,这样如果父文件夹不包含ProdStream,就不用再看其他东西了。

答案 1 :(得分:1)

如果适合你,试试这个:

For /f "delims=" %%a in ('dir /ad/b/s c:\yourfolder\*Prodstream*') do (
forfiles /P "%%~fa" /M *.flv /D -90 /C "cmd /C move @file "DEST_PATH""
)