我使用 Perforce,在取消搁置后经常会有许多本地更改,我想将其删除。使用 PowerShell,我可以打印出我想要删除的文件,但输出字符串仍然包含我想要删除的子字符串。
Get-ChildItem -Recurse -Include ("*.uasset", "*.umap") -Attributes !ReadOnly "C:\Unreal\Project\Content" | ForEach-Object {p4 have $_.FullName}
这会将我仅在本地拥有的文件输出为“C:\Unreal\Project\File.uasset - 文件不在客户端”。和其他“//Project/Content/File.uasset#12 - C:\Unreal\Project\File.uasset”
我想删除客户端上没有的文件,而另一个运行
p4 sync
,但目前即使让 Write-Host 仅使用本地路径输出也卡住了。
我尝试使用 Select-String 过滤输出,然后尝试仅输出类似的路径
Get-ChildItem -Recurse -Include ("*.uasset", "*.umap") -Attributes !ReadOnly "C:\Unreal\Project\Content" | ForEach-Object {p4 have $_.FullName} | Select-String " not on client." | Write-Host ($_ -split ' - file(s)')[0]
完整字符串“C:\Unreal\Project\File.uasset - 文件不在客户端。”仍然被打印
还尝试像这样在循环内进行过滤
Get-ChildItem -Recurse -Include ("*.uasset", "*.umap") -Attributes !ReadOnly "C:\Unreal\Project\Content" | ForEach-Object { if ((p4 have $_.FullName) -like "*not on client." { Write-Host ($_ -split ' - file(s)')[0] } }
再次将完整字符串打印到终端。
我尝试过像
$_.Split(' - file(s)', 2)[0]
这样的拆分变体,但仍然打印出完整的字符串。为了确保这一点,如果 split 将完整字符串作为第一个索引,然后得到 split 结果,我尝试了不同的索引。
未过滤输出示例
> Get-ChildItem -Recurse -Include ("*.uasset", "*.umap") -Attributes !ReadOnly "C:\Unreal\Project\Content" | ForEach-Object {p4 have $_.FullName}
C:\Unreal\Project\Content\Example_01.uasset - file(s) not on client.
C:\Unreal\Project\Content\Example_02.uasset - file(s) not on client.
C:\Unreal\Project\Content\Example_03.uasset - file(s) not on client.
//Project/Content/Example_04.uasset#11 - C:\Unreal\Project\Content\Example_04.uasset
//Project/Content/Example_05.uasset#6 - C:\Unreal\Project\Content\Example_05.uasset
//Project/Content/Example_06.uasset#1 - C:\Unreal\Project\Content\Example_06.uasset
//Project/Content/Example_07.umap#7 - C:\Unreal\Project\Content\Example_07.umap
//Project/Content/Example_08.umap#73 - C:\Unreal\Project\Content\Example_08.umap
C:\Unreal\Project\Content\Example_09.uasset - file(s) not on client.
C:\Unreal\Project\Content\Example_10.uasset - file(s) not on client.
C:\Unreal\Project\Content\Example_11.uasset - file(s) not on client.
C:\Unreal\Project\Content\Example_12.uasset - file(s) not on client.
C:\Unreal\Project\Content\Example_13.uasset - file(s) not on client.
我猜你还可以注意到,p4 命令会将“文件不在客户端”打印到 stderr,因为这是一个错误/警告 - 在我放弃 powershell 并在 python 中完成后发现的。
凝聚大家的努力:
# Get the files
Get-ChildItem -Recurse -Include ('*.uasset', '*.umap') -Attributes !ReadOnly 'C:\Unreal\Project\Content' |
# run "p4 have" on every file
# we are only interested in the results sent to stdErr\Error Stream, so redirect it to stdOut\Success Stream
ForEach-Object { p4 have $_.FullName 2>&1 } |
# Filter keeping only the ones we need
Where-Object { $_ -like '*not on client.' } |
# for each string, remove the undesidered parts(everything after the filename)
ForEach-Object { $_.Substring($_.IndexOf(' - file(s)')) }
它返回带有完整路径的文件名字符串数组