簡體   English   中英

如何在PowerShell對象中存儲文件列表?

[英]How can I store a list of files in a PowerShell object?

我有以下代碼:

$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

這將創建我的代碼使用的adminFiles列表和userFiles列表。

但是我有一個問題,有些文件位於wwwroot下的目錄中。 所以我需要在這里觀看文件:

\content\less\_dark.less
\content\less\_light.less
\lib\abc.txt
\index.txt

有人可以幫忙建議我如何更改此代碼,以便它與目錄一起工作,然后與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

您需要針對包含部分路徑的數組過濾$_.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 我確實聽到的與眾不同的是創建一個從文本文件路徑構建的正則表達式字符串。 另外,我通過組合兩個調用Get-ChildItem的輸出來應用過濾器

$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()可以轉義任何可能出現在字符串中的正則表達式控制字符,例如句點。 我們使用-join創建一個匹配組。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM