
我發現這樣可以取得 CSV 檔案中資料夾及其子資料夾(僅限檔案)的內容:
dir -recurse | Where-Object { !$_.PSIsContainer } | Select FullName |
convertto-csv | out-file "test.csv"
但是,我想獲取相對路徑(相對於運行命令的根目錄),而不是完整路徑。
有人可以幫忙嗎?
謝謝!
答案1
獲取正確的 Csv 檔案的一種方法是包裝我的評論的輸出:
Get-ChildItem -Recurse -Name -File |
ForEach-Object -begin {'"RelativePath"'}{'"{0}"' -f $_}|
Out-File "test.csv"
或使用計算屬性從屬性中移除起始目錄FullName
。
$StartDir = "$ENV:USERPROFILE\Documents\"
Get-ChildItem -Path $StartDir -File -Recurse |
Select-Object @{n='RelativePath';e={$_.FullName -replace [regex]::escape($StartDir)}}|
Export-Csv 'test.csv' -NoTypeInformation
答案2
這個問題會讓人覺得您對 PowerShell 非常陌生。因此,至關重要的是,你要加強力,以限制/避免你肯定會遇到的誤解、壞習慣、錯誤和嚴重的挫折感。造訪 YouTube/MSDN Channel9 並搜尋初級、中階、進階 PowerShell,以及 PowerShell 檔案系統管理和 PowerShell 檔案和資料夾管理。
在許多情況下,PowerShell 會嘗試強制執行某些操作,但它不會嘗試找出您想要執行的操作。你必須告訴它要做什麼。嗯,這對於任何電腦語言都是如此。
你的問題是你說的......
(相對於我運行命令的根目錄)
……好吧,您可能位於距根驅動器 X 級深的路徑中,因此,現在您處於子級中,並且推斷您只希望從子級中獲得此資訊。這就是這個思考過程的問題。
將其保存到文字檔案中,然後就永遠不會有磁碟機路徑,因此當您返回使用它時,您必須知道這一點並手動將其放回以便再次使用這些檔案。
所以,我不確定你的用例是什麼,但從邏輯上講,它會反過來咬你。
那麼,假設我在這裡:
Push-Location -Path 'E:\Temp'
然後我們運行這個
Get-ChildItem -recurse |
Where-Object { !$_.PSIsContainer } | Select-Object -Property FullName
# Results
FullName
--------
E:\Temp\about_ReGet-ChildItemection Microsoft Docs.url
...
E:\Temp\ZipMultiFolder.zip
E:\Temp\Folder\Log_20190419.txt
...
E:\Temp\Reports\NewFiles.zip
...
所以,在這裡我們只是獲取當前位置...
Get-ChildItem -recurse |
Where-Object { !$_.PSIsContainer } |
Select-Object -Property @{Name = 'RelativePath';Expression = {"\$($pwd.Drive.CurrentLocation)\$($PSItem.Name)"}}
所以,在這裡我們只取得目前所在的路徑,只詢問檔名,而不是全名
# Results
RelativePath
------------
\Temp\about_ReGet-ChildItemection Microsoft Docs.url
...
\Temp\ZipMultiFolder.zip
\Temp\Folder\Log_20190419.txt
...
\Temp\Reports\NewFiles.zip
...
如果我們將其輸出到 CSV,您將不知道它來自哪個磁碟機。因此,現在您必須搜尋電腦上的每個驅動器才能找到它們,或記住執行此操作時您所在的位置。
讓孩子摔倒,同樣的事情。當然,你明白了,但它到底在哪裡呢?在您的系統上,或在您對應到的某個網路磁碟機上。
Push-Location -Path 'E:\Temp\Folder'
然後我們運行這個
Get-ChildItem -recurse |
Where-Object { !$_.PSIsContainer } | Select-Object -Property FullName
# Results
FullName
--------
E:\Temp\Folder\Log_20190419.txt
E:\Temp\Folder\New Bitmap Image.bmp
E:\Temp\Folder\New Text Document - Copy.txt
E:\Temp\Folder\New Text Document.txt
Get-ChildItem -recurse |
Where-Object { !$_.PSIsContainer } |
Select-Object -Property @{Name = 'RelativePath';Expression = {"\$($pwd.Drive.CurrentLocation)\$($PSItem.Name)"}}
RelativePath
------------
\Temp\Folder\Log_20190419.txt
\Temp\Folder\New Bitmap Image.bmp
\Temp\Folder\New Text Document - Copy.txt
\Temp\Folder\New Text Document.txt
如果你在這裡說,你不想要父根,那麼你就將其關閉。
然而,這意味著,您不僅不知道它來自哪個驅動器,而且也不知道其中的根父級來自哪個驅動器。
所以,就說吧。
順便說一句,最佳實踐是在腳本中使用完整的 cmdlet 名稱。速記/別名非常適合互動式內容。當然,我們都習慣使用“dir”,但是 Get-ChildItem 的簡寫是“gci”,它和以前一樣短,但是,你知道。
Get-Alias -Definition Get-ChildItem |
Format-Table -AutoSize
CommandType Name Version Source
----------- ---- ------- ------
Alias dir -> Get-ChildItem
Alias gci -> Get-ChildItem
Alias ls -> Get-ChildItem
但是,嘿,習慣真的很難打破。 ;-} --- --- 謹慎的決定是那些對我們有用的決定,無論其他人怎麼想。 ;-}
好吧,那些追隨你的人表明了立場。因此,成為一名優秀的 PowerShell 公民確實是一件好事。
順便說一句,如果您打算在腳本中執行此操作,那麼也有一個自動變數可以用於此類操作。好吧,獲取運行腳本的位置以及該位置中關聯的任何內容。
請參閱這篇文章。