[英]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.