使用 Powershell 删除文件名中的括号字符

使用 Powershell 删除文件名中的括号字符

我在 Sharepoint 服务器上存储了一个大型文档库,该文档库已从旧的 Access 数据库迁移过来,这些文档的版本由用户控制,并在进行更改时附加在文件名的末尾。

例如

  1. Doc1-测试(1.0).doc
  2. Doc1-测试(1.1).doc
  3. Doc2-示例(2.1).doc
  4. Doc2-示例(2.2).doc

我们现在使用 Sharepoint 来控制版本,需要删除文件名中的版本。

我已经通过以下脚本取得了一定的成功;

gi * | % { rni $_ ($_.Name -replace '(1.0)', '') }

但我无法让它从文件名中删除括号。因此,在我的测试目录中,文件更改为以下内容

Doc1-doc(1.0).doc ----- Doc1-doc().doc

数字范围从 1.0 到 4.5 左右,并且有超过 1200 个文档,所以我不介意为每个版本号使用单独的脚本。

答案1

你遇到的问题是 PowerShell 的-replace使用常用表达进行搜索。

()这意味着搜索查询中的括号 ( ) 被解释为正则表达式捕获组

在这种情况下,您希望将它们引用为文字字符,因此需要对括号进行转义。在 RegEx 中,这是通过反斜杠 ( \) 来完成的。

所以就-replace '\(1.0\)',''应该这么做。

由于你使用的是 RegEx,因此你可以利用它并通过指定“数字”字符类或字符“集”而不是实际的版本号,因为您的搜索模式

因此类似于:

gi * | % { rni $_ ($_.Name -replace '\(1.[0-9]\)', '') }

(1.<any number from 0 to 9>)将从文件名中删除。

如果你想删除括号和任何事物在它们之间,您可以使用“任意字符(.)任意次数(*)”RegEx 模式:

IE:-replace '\(.*\)',''

注意:RegEx 可能会让您感到惊讶(在这种情况下,请考虑单个文件名中的外部和内部括号),因此请先备份您的文件并运行测试。:)

答案2

但我无法让它从文件名中删除括号。因此,在我的测试目录中,文件更改为以下内容

Doc1-doc(1.0).doc ----- Doc1-doc().doc

这是因为replace使用正则表达式和括号(捕获组)应该被转义。转义所有文本的最简单方法是使用[正则表达式]::转义方法:

gi * | % { rni $_ ($_.Name -replace [regex]::Escape('(1.0)'), '') }

请注意,删除括号中的所有内容都会对文件产生冲突,例如Doc1-test(1.1).docDoc1-test(1.0).doc- 它们都将被映射到Doc1-test.doc

这是我的正则表达式版本,它只匹配文件名末尾括号内以点分隔的数字(不带扩展名)。我没有在此代码中处理文件名冲突,因为我不知道您想要的结果。

# Get all objects in current directory that match wildcard: *(*.*).doc
Get-ChildItem -Path '.\' -Filter '*(*.*).doc' |
    # Skip folders, because XXX(1.1).doc is a valid folder name
    Where-Object {!$_.PSIsContainer} |
        # For each file
        ForEach-Object {
            # New file name = 
            # File Directory + (File name w\o extension with regex pattern (\(\d+\.\d+\))$ replaced with empty string) + File extension

            # Note, that it will create confilcts for files such as Doc1-test(1.1).doc and Doc1-test(1.0).doc,
            # both of them will end with name Doc1-test.doc
            $NewFileName = Join-Path -Path $_.DirectoryName -ChildPath (($_.BaseName -replace '(\(\d+\.\d+\))$', [string]::Empty) + $_.Extension)

            # Basic logging
            Write-Host "Renaming: $($_.FullName) -> $NewFileName"

            # Rename file.
            Rename-Item -Path $_.FullName -NewName $NewFileName
        }

解释正则表达式(\(\d+\.\d+\))$

1st Capturing group (\(\d+\.\d+\))

\( matches the character ( literally

\d+ match a digit [0-9]
Quantifier: + Between one and unlimited times,
as many times as possible, giving back as needed [greedy]

\. matches the character . literally

\d+ match a digit [0-9]
Quantifier: + Between one and unlimited times,
as many times as possible, giving back as needed [greedy]

\) matches the character ) literally

$ assert position at end of the string

相关内容