2015-04-22 111 views
3

我正在使用PowerShell,並且我在這個問題上苦苦掙扎了兩天。將包含字符串的文件移動到與原始文件夾名稱相同的子文件夾(PowerShell)

在目錄C:\ dir_1我有許多子文件夾(sub_1,sub_2,...,sub_n)。他們每個人都包含幾個文本文件。對於每個子文件夾i = 1,2,...,n,我想將包含字符串「My-String」的文本文件移動到目錄C:\ dir_2 \ sub_i。

例如,如果路徑C:\ dir1 \ sub_5中的文件X包含字符串「我的字符串」,我想將其移動到位置C:\ dir_2 \ sub_5。目標文件夾已存在。

我嘗試下面的代碼的一些修改,但它不工作:

Get-ChildItem "C:\dir_1" | Where-Object {$_.PSIsContainer -eq $True} | Foreach-Object {Get-ChildItem "C:\dir_1\$_" | Select-String -pattern "My-String" | group path | select name | %{Move-Item $_.name "C:\dir_2\$_"}} 

所以,基本上,我試圖做的是:在DIR_1的foreach子文件夾中,服用含有該字符串的文件和將它們移動到dir_2中具有相同名稱的子文件夾中。我嘗試了幾次對該代碼的小修改,但我無法解決我的錯誤。主要的錯誤是「移動項目:給定的路徑格式不支持」...任何幫助?

+0

要嘗試和意譯:您正在查找包含某個字符串的dir_1 \ Sub_X中的文件。對於找到的所有文件,將它們移動到dir_2 \ SUB_X中?其中sub_X是同一個文件夾,它在dir_1裏面......我想我明白了。 – Matt

+0

正確,你得到它:) –

回答

5

我覺得我可以做的更好,但是這是我的第一種方法

$dir1 = "C:\temp\data\folder1" 
$dir2 = "C:\temp\data\folder2" 

$results = Get-ChildItem $dir1 -recurse | Select-String -Pattern "asdf" 

$results | ForEach-Object{ 
    $parentFolder = ($_.Path -split "\\")[-2] 
    Move-Item -Path $_.Path -Destination ([io.path]::combine($dir2,$parentFolder)) 
} 

Select-String可以利用文件路徑的管道輸入。我們使用-recurse將所有$dir1下的文件送到子文件夾中。 $results將包含匹配對象的數組。其中一個屬性是匹配文件的路徑。

以上所有這些$results我們然後通過每個並從路徑中提取父文件夾。然後將該文件夾與路徑$dir2合併,以便將其移動到目標位置。

我們在這裏有幾個假設。有些我們可以說明是否需要。我會提到我所知道的可能是第一個問題。

  1. 您的文件夾不應該在「sub_1,sub_2,...,sub_n」下面有任何其他子文件夾,否則他們會嘗試錯誤地移動。這可以通過更多的字符串操作來解決。爲了使代碼簡潔,使用-Recurse創建了此警告。
+0

馬特,你是天才! :D它的工作:) 非常感謝你!我想upvote你的答案,但我仍然不能(我是newbe:P) 編輯:的確,沒有其他子文件夾下「sub_1,sub2,...,sub_n」。所以它非常完美 –

1

這裏是一個班輪,你想要做什麼太:

Get-ChildItem "C:\dir_1" | Where-Object {$_.PSIsContainer -eq $True} | ForEach-Object {$SubDirName = $_.Name;ForEach ($File in $(Get-ChildItem $_.FullName)){If ($File.Name -like "*My-String*"){Move-Item $File.FullName "C:\dir_2\$SubDirName"}}} 

如果你想看到它打破了像馬特的答案:

$ParentDir = Get-ChildItem "C:\dir_1" | Where-Object {$_.PSIsContainer -eq $True} 
ForEach ($SubDir in $ParentDir){ 
    $SubDirName = $SubDir.Name 
    ForEach ($File in $(Get-ChildItem $SubDir.FullName)){ 
     If ($File.Name -like "*My-String*"){ 
      Move-Item $File.FullName "C:\dir_2\$SubDirName" 
     } 
    } 
} 
+1

你幾乎可以將所有的代碼寫成一行代碼! – Matt

相關問題