如何在PowerShell对象中存储文件列表?

如何在PowerShell对象中存储文件列表?,powershell,Powershell,我有以下代码: $filestowatch=get-content C:\GT\files-to-watch.txt $adminFiles=dir C:\GT\admin\src\admin\wwwroot\content\less\ |? {$filestowatch -contains $_.Name} $userfiles=dir C:\GT\user-staging\src\user_staging\wwwroot\content\less\|? {$filestowatch -co

我有以下代码:

$filestowatch=get-content C:\GT\files-to-watch.txt
$adminFiles=dir C:\GT\admin\src\admin\wwwroot\content\less\ |? {$filestowatch -contains $_.Name}
$userfiles=dir  C:\GT\user-staging\src\user_staging\wwwroot\content\less\|? {$filestowatch -contains $_.Name}
以及在files-to-watch.txt中

_dark.less
_light.less
这将创建我的代码使用的AdminFile列表和UserFile列表

但是,我有一个问题,一些文件位于wwwroot下的目录中。所以我需要看一下这里的文件:

\content\less\_dark.less
\content\less\_light.less
\lib\abc.txt
\index.txt
有人可以帮助我,并建议我如何更改此so代码,使其与目录一起工作,然后与files-to-watch.txt中的文件名一起工作

更新-这是我提出的完整代码,我尝试了vesper的建议,但它似乎与我的代码不兼容

$filestowatch=get-content C:\GT\files-to-watch.txt

$adminFiles=dir C:\GT\admin\src\admin\wwwroot -recurse | 
    ? { $fn=$_.FullName; ($filestowatch | % {$fn.contains($_)}) -contains $True}

$userFiles=dir C:\GT\user-staging\src\user-staging\wwwroot -recurse | 
    ? { $fn=$_.FullName; ($filestowatch | % {$fn.contains($_)}) -contains $True}

foreach($userfile in $userFiles)
{
   Write-Host "Checking" $userfile.FullName 

      $exactadminfile= $adminfiles | ? {$_.Name -eq $userfile.Name} |Select -First 1
      $filetext1=[System.IO.File]::ReadAllText($exactadminfile.FullName)
      $filetext2=[System.IO.File]::ReadAllText($userfile.FullName)
      $equal = $filetext1 -ceq $filetext2 # case sensitive comparison

      if ($equal) { break; }

      if($exactadminfile.LastWriteTime -gt $userfile.LastWriteTime)
      {
         Write-Host "Copying  $exactadminfile.FullName to $userfile.FullName "
         Copy-Item -Path $exactadminfile.FullName -Destination $userfile.FullName -Force
       }
       else
       {
          Write-Host "Copying  $userfile.FullName to $exactadminfile.FullName "
          Copy-Item -Path $userfile.FullName -Destination $exactadminfile.FullName -Force
       }
}
还有我要看的文件

content\less\_dark.less
content\less\_light.less
我认为这很接近,但它给了我一个错误:

PS C:\Windows\system32> C:\GT\watcher.ps1
dir : Cannot find path 'C:\GT\user-staging\src\user-staging\' because it does not exist.
At C:\GT\watcher.ps1:8 char:12
+ $userFiles=dir C:\GT\user-staging\src\user-staging\wwwroot -recurse |
+            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (C:\GT\user-staging\src\user-staging\:String) [Get-ChildItem], ItemNotFoundException
    + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetChildItemCommand

您需要根据包含部分路径的数组筛选
$\uU4.FullName
。比如说,您的
$filestowatch
包含您列出的值。然后,您可以使用从
$中快速生成一个“任意匹配”筛选器。FullName

$adminFiles=dir C:\GT\admin\src\admin\wwwroot -recurse | 
    ? { $fn=$_.FullName; ($filestowatch | % {$fn.contains($_)}) -contains $True}

这将对生成布尔数组的
$filestowatch
运行子字符串检查,如果其中任何一个是
$True
,则存在匹配,而
Where Object
过滤器将找到的
FileInfo
对象通过管道传递。

您需要针对包含部分路径的数组过滤
$\FullName
。比如说,您的
$filestowatch
包含您列出的值。然后,您可以使用从
$中快速生成一个“任意匹配”筛选器。FullName

$adminFiles=dir C:\GT\admin\src\admin\wwwroot -recurse | 
    ? { $fn=$_.FullName; ($filestowatch | % {$fn.contains($_)}) -contains $True}

这将对生成布尔数组的
$filestowatch
运行子字符串检查,如果其中任何一个是
$True
,则存在匹配,而
Where Object
过滤器通过管道传递找到的
FileInfo
对象。

我将文件和文件夹路径分解为变量,这使得测试和可读性更容易。当然,如果你认为合适,可以随意改变。与Vesper非常相似,如果您关心父目录中的文件,则需要使用
-recurse
。我听说不同的是创建一个正则表达式字符串,它是从文本文件中的路径构建的。此外,我还通过组合调用的两个函数的输出来应用一次过滤器,以
getchilditem

$adminfilePath = "C:\GT\admin\src\admin\wwwroot"
$userfilePath = "C:\GT\user-staging\src\user_staging\wwwroot"
$filesToWatchPath = "C:\GT\files-to-watch.txt"

$filter = (Get-Content $filesToWatchPath | ForEach-Object{[regex]::Escape($_)}) -join "|"
$adminFiles = @(Get-ChildItem $adminfilePath  -Recurse | Select-Object -ExpandProperty FullName)
$userfiles = @(Get-ChildItem $userfilePath -Recurse | Select-Object -ExpandProperty FullName)

$adminFiles + $userfiles | Where-Object{$_ -match $filter}
使用您的示例文本,我们创建一个如下所示的过滤器

_dark\.less|_light\.less

使用
[regex]::Escape()
我们可以转义字符串中可能出现的任何regex控制字符,如句点。我们使用
-join
创建匹配组

我将文件和文件夹路径分解为变量,这使得测试和可读性更容易。当然,如果你认为合适,可以随意改变。与Vesper非常相似,如果您关心父目录中的文件,则需要使用
-recurse
。我听说不同的是创建一个正则表达式字符串,它是从文本文件中的路径构建的。此外,我还通过组合调用的两个函数的输出来应用一次过滤器,以
getchilditem

$adminfilePath = "C:\GT\admin\src\admin\wwwroot"
$userfilePath = "C:\GT\user-staging\src\user_staging\wwwroot"
$filesToWatchPath = "C:\GT\files-to-watch.txt"

$filter = (Get-Content $filesToWatchPath | ForEach-Object{[regex]::Escape($_)}) -join "|"
$adminFiles = @(Get-ChildItem $adminfilePath  -Recurse | Select-Object -ExpandProperty FullName)
$userfiles = @(Get-ChildItem $userfilePath -Recurse | Select-Object -ExpandProperty FullName)

$adminFiles + $userfiles | Where-Object{$_ -match $filter}
使用您的示例文本,我们创建一个如下所示的过滤器

_dark\.less|_light\.less

使用
[regex]::Escape()
我们可以转义字符串中可能出现的任何regex控制字符,如句点。我们使用
-join
创建匹配组

谢谢。与您编写的常规代码相比,所有这些看起来都相当复杂。我从你的答案中学到了很多。我尝试了你的建议。我认为它几乎起作用了,但我得到了另一个错误,不确定它是否与你的建议有关。你有什么想法吗?你打错了第二个
用户登台
,根据你原来的代码,有一个下划线。下次小心点,谢谢。与您编写的常规代码相比,所有这些看起来都相当复杂。我从你的答案中学到了很多。我尝试了你的建议。我认为它几乎起作用了,但我得到了另一个错误,不确定它是否与你的建议有关。你有什么想法吗?你打错了第二个
用户登台
,根据你原来的代码,有一个下划线。下次要小心。