我在 Sharepoint 服务器上存储了一个大型文档库,该文档库已从旧的 Access 数据库迁移过来,这些文档的版本由用户控制,并在进行更改时附加在文件名的末尾。
例如
- Doc1-测试(1.0).doc
- Doc1-测试(1.1).doc
- Doc2-示例(2.1).doc
- 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).doc
和Doc1-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