2017-08-12 64 views
0

我在特定目錄和子目錄中有數千個文件。使用Powershell替換目錄名稱,文件名和文件內容中的字符串

  • C:\Food\
  • C:\Food\Avocado.sln(還包含字符串 「鱷梨」)
  • C:\Food\Avocado.DataModel\
  • C:\Food\Avocado.DataModel\AvocadoModel.cs(還包含字符串 「鱷梨」)

我想全部更換在目錄名稱中帶有「Burger」的字符串「Avocado」的實例,文件名和文件內容例如

  • C:\Food\
  • C:\Food\Burger.sln(所有intances 「在文件內容鱷梨現改爲 」漢堡「)
  • C:\Food\Burger.DataModel\
  • C:\Food\Burger.DataModel\BurgerModel.cs(所有intances」 在文件內容鱷梨現改爲 「漢堡」 )

我想使用Powershell來做到這一點。

我該怎麼做?

+0

什麼文件類型檢查,只有'.sln'和'.cs'?只檢查包含鱷梨或一般文件夾中的文件?只有在文件名或全部文件中才檢查內容鱷梨的文件? – LotPings

+0

@LotPings所有文件。我正在學習如何使用PowerShell,因此在下面發佈了我的答案。我相信還有其他(更好的)方法可以實現我想要的。我也意識到,當我的目錄conatins二進制文件時,我的解決方案可能存在問題(所以對於我的情況,我刪除了\ bin和\ obj目錄) –

回答

0

我用下面的腳本來改變目錄名,文件名和文件內容。我知道可能有更簡單的方法來使用管道運營商|來做到這一點,但這對我來說很有意義(我對Powershell來說相對較新)。

# change these three variables to suit your requirements 
$baseDirectory = "C:\Food\" 
$a = "Avocado" 
$b = "Burger" 

# get all files 
$files = Get-ChildItem $baseDirectory -File -Recurse 
# get all the directories 
$directorys = Get-ChildItem $baseDirectory -Directory -Recurse 

# replace the contents of the files only if there is a match 
foreach ($file in $files) 
{ 
    $fileContent = Get-Content -Path $file.FullName 

    if ($fileContent -match $a) 
    { 
     $newFileContent = $fileContent -replace $a, $b 
     Set-Content -Path $file.FullName -Value $newFileContent 
    } 
} 

# change the names of the files first then change the names of the directories 

# iterate through the files and change their names 
foreach ($file in $files) 
{ 
    if ($file -match $a) 
    { 
     $newName = $file.Name -replace $a, $b 
     Rename-Item -Path $file.FullName -NewName $newName 
    } 
} 

# reverse the array of directories so we go deepest first 
# this stops us renaming a parent directory then trying to rename a sub directory which will no longer exist 
# e.g. 
# we might have a directory structure "C:\Rename\Rename" 
# the file array would be [ C:\Rename, C:\Rename\Rename ] 
# without reversing we'd rename the first directory to "C:\NewName" 
# the directory structure would now be "C:\NewName\Rename" 
# we'd then try to rename C:\Rename\Rename which would fail 
[array]::Reverse($directorys) 

# iterate through the directories and change their names 
foreach ($directory in $directorys) 
{ 
    if ($directory -match $a) 
    { 
     $newName = $directory.Name -replace $a, $b 
     Rename-Item -Path $directory.FullName -NewName $newName 
    } 
} 
0

我甚至不會嘗試編輯潛在的二進制文件,
所以下面的腳本只處理指定的文件類型
和安全性做了備份。

$baseDirectory = "C:\Food\" 
$a = "Avocado" 
$b = "Burger" 
$Include = '*.sln','*.cs' 


Pushd $baseDirectory 

# process all file and directory names 
Get-ChildItem -Filter "*$a*" -Recurse| 
    Rename-Item -NewName {$_.Name -replace $a,$b} -confirm 


Get-ChildItem -Include $Include -Recurse | ForEach-Object{ 
    if (Select-String -Path $_ -Pattern $a -quiet){ 
    $BakName = "{0}.bak" -f $_.FullName 
    $OldName = $_.FullName 
    $_ | Move-Item -Destination $BakName -force 
    (Get-Content $BakName) -replace $a,$b | Set-Content $OldName 
    } 
} 
PopD 
相關問題