2015-04-23 70 views
-1

我有一個我在公司爲清除Citrix UPM配置文件寫的腳本。不是很複雜,但它爲每個運行用戶生成日誌。隨着格式:如何在Powershell中分割和選擇一組文件名?

UPMreset-e0155555-20150112-0733

UPMreset-n9978524-20150114-1128

UPMreset-JSMITH-20150113-0840

所以我想要抓取包含所有.txt文件的文件夾,只選擇用戶名並計數,看看是否出現超過特定次數的文件夾。檢查有問題的孩子。把它們放入一個數組很容易,但是在做一個-split時,我似乎找不到一個正則表達式組合來選擇只有用戶名。我以爲我可以做一個(' - ')[1],但這似乎並不奏效。你有什麼建議嗎?

$arrFiles = Get-Childitem "c:\logs" 
$arrFiles | %{ $arrfile = $_ -split ('-'); Write-Host $arrfile[0]} 

編輯:包括後代的測試代碼。

+0

得到了我的答案,但包括我使用的測試代碼。它只會在連字符之前抓取項目。添加[1]將不會輸出任何內容。有理由嗎? –

回答

2

我想嘗試這樣的事:

$Path = 'N:\Folder\*.txt'; 

Get-ChildItem $Path | 
    ForEach-Object { 
     Write-Output $_.BaseName.Split('-')[1]; 
    } | 
    Group-Object | 
    Where-Object { $_.Count -gt 1 } | 
    Sort-Object -Property Name | 
    Select-Object Name, Count; 

要回答題。

$_是由Get-ChildItem返回的對象之一。這些對象是而不是字符串。它們是。System.IO.DirectoryInfoSystem.IO.FileInfo類型的.Net對象。這意味着如果我們使用$_,我們引用整個對象。更糟的是,這些對象都沒有Split()方法,所以$_.Split('-')會引用一個不存在的函數。

BaseName是FileInfo或DirectoryInfo對象的屬性。該屬性包含沒有路徑或擴展名的文件的名稱。重要的是,這個屬性也是一個字符串,其中確實有Split()方法。所以使用這個屬性會做兩件事:它刪除路徑名和擴展名,因爲我們不關心這個,我們不希望它有可能破壞某些東西(例如,如果有人在父文件夾的名字中加上破折號),它給了我們一個String對象,我們可以使用String方法來操作,並執行諸如調用Split函數之類的操作。

在命令行中嘗試是這樣的:

$x = Get-ChildItem 'N:\Folder\UPMreset-e0155555-20150112-0733.txt'; 
$x | Get-Member; 

你會得到一個巨大的物體的方法(函數)該對象可以做和屬性(屬性值)的列表。名稱,FullName,BaseName和Extension都是非常常用的屬性。您還應該看到由PowerShell提供者添加的NoteProperties和CodeProperties,以使它們更容易使用(它們在C#程序中不可用)。該定義告訴您如何調用該方法或該屬性的類型以及您可以使用的方式。您通常可以通過Google找到MSDN文檔,瞭解如何使用它們,但這並不總是最簡單的方法。

比較上述這樣:

$x.BaseName | Get-Member; 

你可以看到,這是一個字符串,有各種樣拆分方法,替換的IndexOf等

另一個有用的一個是:

$x | Select-Object *; 

這將返回此對象具有的所有Propety,NoteProperty和CodeProperty值。

這突出了一個最好的方法來了解你可以用一個對象做什麼。將其管理到Get-Member,您將瞭解可以訪問的類型和任何方法或屬性。這與管道輸送到Select-Object *相結合,可以告訴你很多關於你的工作。

+0

多個很好的答案,但這對我所嘗試的完美。將BaseName添加到拆分變更是什麼? –

+0

@JoshuaKoffski查看更新。 –

+0

簡明而翔實。謝謝你的建議。 –

1

它看起來像文件名總是UPMreset-,其次是用戶名。因此,使用這樣的:

UPMreset-(.+?)-

和捕獲組將包含用戶名。它使用一個懶惰的量詞來獲得下一個短劃線。

3

您與.split('-')[1]有什麼問題?

$filenames = @(
'UPMreset-e0155555-20150112-0733', 
'UPMreset-n9978524-20150114-1128', 
'UPMreset-jsmith-20150113-0840' 
) 

$filenames |% {$_.split('-')[1]} 

e0155555 
n9978524 
jsmith 
1

你也可以做分割的計算性能與集團目標:

$FileNames = Get-ChildItem -Path $LogDir -Filter "*.txt" -Name 

$FileNames | Group-Object @{Expression={($_ -split "-")[1]}} | Where-Object {$_.Count -gt 1}