使用PowerShell对文件名和目录执行操作

时间:2016-04-11 18:51:46

标签: powershell batch-file

我尝试使用设置目录中的文件夹和文件名进行某些特定操作。

  • 我没有替换下划线(" _")("")
  • 我没有替换空格("")("")
  • 我用小写的hp和空格替换小写的hp(" hp")(" HP &#34)
  • 我用大写的hp和空格替换大写的hp(" HP")(" HP &#34)
  • 我用大写的hp和空格代替camelcase hp(" Hp")(" HP ")
  • 我用小写字母替换小写字母a(" a") a(" A")... B ... C等。

这是我的powershell脚本:

HP 14-Z040wm

我知道,它本质上是一堆循环。

我有几个问题和疑问:

  1. 上面的代码无效用小写字母(a-z)替换小写字母,为什么会这样?它似乎也无法一直递归地工作。 E.G文件夹名称HP14-Z040WM,里面的文件是{{1}}
  2. 我怎样才能最终使这个脚本变得更好?如更短,更快等。
  3. (我也批量批处理文件,因为我绝对接受(我开始制作时的第一选择)批量文件解决方案。

2 个答案:

答案 0 :(得分:3)

首先,只获取一次物品,然后处理一次。接下来,您可以使用ToUpper()方法替换字符替换。第三,由于所有这些方法都返回字符串,因此您可以将这些方法链接在一起。

文件很简单:

Get-ChildItem -Recurse -File | ForEach-Object {
    $NewName = $_.Name.ToUpper().Replace('_','').Replace(' ','').Replace('HP', 'HP ');
    Rename-Item -Path $_.FullName -NewName $NewName;
}

然而,文件夹是另一个蜡球。您不能将文件夹路径重命名为同一名称,并且路径名不区分大小写。因此Rename-ItemMove-Item都无法独立运作。您必须使用临时文件夹名称。

以下是文件和文件夹的代码:

#Unique name for temp folder
$TempFolderName = [System.Guid]::NewGuid().Guid;

Get-ChildItem -Recurse | ForEach-Object {
    $NewName = $_.Name.ToUpper().Replace('_','').Replace(' ','').Replace('HP', 'HP ');
    if (!$_.PSIsContainer) {
        #Regular file
        Rename-Item -Path $_.FullName -NewName $NewName;
    }
    else {
        #Get the parent folder
        $ParentFolder = Split-Path $_.FullName;

        #Rename folder to temp name
        Rename-Item -Path $_.FullName -NewName (Join-Path $ParentFolder $TempFolderName);

        #Rename temp name to folder
        Rename-Item -Path (Join-Path $ParentFolder $TempFolderName) -NewName (Join-Path $ParentFolder $NewName);
    }
}

答案 1 :(得分:1)

您应首先重命名文件然后重命名文件夹。尝试同时执行这两个操作可能会使管道中的其他对象失效并导致错误。此处的重复也可以使用-replace "\s|_" and保存.ToUpper(). - replace`是一个正则表达式函数,我们用它来替换所有空格和下划线。你也可以链接这些,所以我们也将在名称的开头替换HP并添加空间。

$path = "C:\Temp"
Get-ChildItem $path -Recurse -Directory | Rename-Item -NewName {($_.Name).ToUpper() -replace "\s|_"} -WhatIf
Get-ChildItem $path -Recurse -File | Rename-Item -NewName {($_.Name).ToUpper() -replace "\s|_"} -WhatIf

我已将-WhatIf放在那里进行测试。如果此代码仅改变实体名称的大小写,那么它将给出一个错误,即文件/文件夹名称需要不同(文件夹不区分大小写)。所以你需要先将它移动到一个临时文件夹。 Windows不区分大小写,因此它会看到您尝试将对象命名为相同。

您需要非常小心运行此代码,因为它会永久地将文件夹名称更改为临时名称。如果进程失败,则必须手动修复损坏的文件夹。在这种情况下,请查找.bak文件夹。我的测试确实有效,所以希望它只是一个预防措施。运行您自己的测试以确定。

$path = "C:\Temp"

# Rename folders
Get-ChildItem $path -Recurse -Directory | ForEach-Object{
    # Save the current name
    $originalName = $_.Name
    # Make sure the temp name is unique.
    $temp = Rename-Item -Path $_.FullName -NewName "$originalName.bak" -PassThru
    # Rename using the saved name and proposed changes.
    $temp | Rename-Item -NewName ($originalName.ToUpper() -replace "\s|_" -replace "^HP","HP ")
} 

Get-ChildItem $path -Recurse -File | Rename-Item -NewName {$_.Name.ToUpper() -replace "\s|_" -replace "^HP","HP "}