Powershell 批量文件重命名-提取父文件夹名称并在文件重命名中使用
PowerShell新手在这里再次与我的概念证明 下面的代码成功地从文件夹中的.msg文件中提取附加文件,并保留提取的文件名,而不进行更改。我现在正在寻找的是提取父文件夹名称的一部分,标准格式为 nnnn+字符串(例如“8322 MyStudy”),即4位数字后跟空格,然后是字符串 …要重命名从中提取的文件名 ExtractedFilename.pdf改为“0nnnn-ExtractedFilename.pdf”。e、 g.“08322-ExtractedFilename.pdf” 我的主要问题是如何提取父文件夹名称的数字部分(从中运行模块)。我希望我糟糕的PS格式化技能能让我完成剩下的工作 再次感谢您的帮助Powershell 批量文件重命名-提取父文件夹名称并在文件重命名中使用,powershell,Powershell,PowerShell新手在这里再次与我的概念证明 下面的代码成功地从文件夹中的.msg文件中提取附加文件,并保留提取的文件名,而不进行更改。我现在正在寻找的是提取父文件夹名称的一部分,标准格式为 nnnn+字符串(例如“8322 MyStudy”),即4位数字后跟空格,然后是字符串 …要重命名从中提取的文件名 ExtractedFilename.pdf改为“0nnnn-ExtractedFilename.pdf”。e、 g.“08322-ExtractedFilename.pdf” 我的主要问题
##
## Source: https://chris.dziemborowicz.com/blog/2013/05/18/how-to-batch-extract-attachments-from-msg-files-using-powershell/
##
## Usage: Expand-MsgAttachment *
##
##
function Expand-MsgAttachment
{
[CmdletBinding()]
Param
(
[Parameter(ParameterSetName="Path", Position=0, Mandatory=$True)]
[String]$Path,
[Parameter(ParameterSetName="LiteralPath", Mandatory=$True)]
[String]$LiteralPath,
[Parameter(ParameterSetName="FileInfo", Mandatory=$True, ValueFromPipeline=$True)]
[System.IO.FileInfo]$Item
)
Begin
{
# Load application
Write-Verbose "Loading Microsoft Outlook..."
$outlook = New-Object -ComObject Outlook.Application
}
Process
{
switch ($PSCmdlet.ParameterSetName)
{
"Path" { $files = Get-ChildItem -Path $Path }
"LiteralPath" { $files = Get-ChildItem -LiteralPath $LiteralPath }
"FileInfo" { $files = $Item }
}
$files | % {
# Work out file names
$msgFn = $_.FullName
# extract path, e.g. 'c:\path\to\'
$msgPath = Split-Path -Path $msgFn
# Skip non-.msg files
if ($msgFn -notlike "*.msg") {
Write-Verbose "Skipping $_ (not an .msg file)..."
return
}
# Extract message body
Write-Verbose "Extracting attachments from $_..."
$msg = $outlook.CreateItemFromTemplate($msgFn)
$msg.Attachments | % {
# Work out attachment file name
#$attFn = $msgFn -replace '\.msg$', " - Attachment - $($_.FileName)"
$attFn = Join-Path -Path $msgPath -ChildPath ($_.FileName)
# Do not try to overwrite existing files
if (Test-Path -literalPath $attFn) {
Write-Verbose "Skipping $($_.FileName) (file already exists)..."
return
}
# Save attachment
Write-Verbose "Saving $($_.FileName)..."
$_.SaveAsFile($attFn)
# Output to pipeline
Get-ChildItem -LiteralPath $attFn
}
}
}
# This function to rename expanded attachment file to study renaming standards
Function RenameExpandedAttachments {
}
End
{
Write-Verbose "Done."
}
}
当前运行的脚本是:
$script:MyInvocation.MyCommand.Path
使用分割路径
仅获取路径
Split-Path $script:MyInvocation.MyCommand.Path
要仅获取最后一个元素,请再次使用带-Leaf参数的splitpath
Split-Path -Leaf (Split-Path $script:MyInvocation.MyCommand.Path)
要提取前导数字,请使用带有(捕获组)的正则表达式
并将所有这些都包装在if中:
If ((Split-Path -Leaf (Split-Path $script:MyInvocation.MyCommand.Path)) -match '^(\d+) (.*)$'){
$NewName = "{0:00000} - {1}" -f $Matches[1],$ExtractedFileName
} else {
"No numbers found in this path"
}
没有必要把你的整个剧本都贴在这里。获得编码经验通常意味着反复尝试,如果你保证每一步都不会走得太远。你不喜欢.Net正则表达式吗<代码>[regex]::匹配($($File.Directory.Name),“^(\d*+)”通过在我的模块中添加此行($myinvocationfolder=Split Path-Leaf(Split Path$script:MyInvocation.MyCommand.Path))尝试使用部分答案。我的调试器暗示“Path”值是我的模块在\My Documents\WindowsPowerShell\Modules\modulename中的位置。我正在查找foldername的名称,用户将从中导入和执行此模块。我还注意到我的变量$myinvocationfolder是空的。这是否澄清了我的要求?Thanks@RobCodyStuff您需要使用
$File.Directory.Name
作为regex
的字符串。这是您的.msg文件的来源,因此它将获取它们所在文件夹的名称。例如C:\Temp\8322 MyStudy\Testfile.msg
$File.Directory.Name
将输出8322 MyStudy
@RobCodyStuff也许我理解了我的主要问题是如何提取父文件夹名称的数字部分(我的模块将从中运行)
错误或它的措辞不吉利。@LotPings我假设他指的是为模块内的函数指定的位置。我可能错了,但我看不到将父文件夹用于模块存储库的实际用途。经典的刺针。
If ((Split-Path -Leaf (Split-Path $script:MyInvocation.MyCommand.Path)) -match '^(\d+) (.*)$'){
$NewName = "{0:00000} - {1}" -f $Matches[1],$ExtractedFileName
} else {
"No numbers found in this path"
}