首页 > 解决方案 > 从Powershell中的下划线和空格划定的文件名中提取单词

问题描述

我正在尝试从文件名中提取两个单词。名称具有以下格式:

__XXXXXXXX_XXX_XXXXXXX_XXXX_XXXXX_XXXX XXX_Aircraft 017_XXXXXXXX-XXXXXXX_XXXXXXX-XXXXXXX-XXXXXX-01Apr2021-XXXXX

X 被替换为不同的单词。我需要提取飞机编号和日期,以便仅使用该信息重命名文件。使用此站点的帮助,我尝试了以下方法来隔离飞机编号:

$names = gci -Path "H:\Path\to\Logs" *.log -Recurse | select @{n="Name"; e={if ($_.Name -match "Aircraft (\w+)") { 
  $matches[1] }}}

但是,它似乎没有给我我需要的比赛。但是,我在编程方面非常不熟练,可能会走错路。我希望用于隔离飞机编号的相同逻辑也适用于日期。

标签: powershellextractfilenames

解决方案


# Create a sample file.
$file = New-Item '__XXXXXXXX_XXX_XXXXXXX_XXXX_XXXXX_XXXX XXX_Aircraft 017_XXXXXXXX-XXXXXXX_XXXXXXX-XXXXXXX-XXXXXX-01Apr2021-XXXXX'

# Substitute your `Get-ChildItem` command for $file
$file |
 Rename-Item -WhatIf -NewName {
   if ($_.Name -match '_(Aircraft \w+?)_.+(\d{2}[a-z]{3}\d{4})-') {
     # Synthesize the new file name from the extracted substrings.
     '{0} - {1}' -f $Matches[1], $Matches[2]
   } else {
     # Input file name didn't match, (effectively) do nothing.
     $_.Name
   }
 }

注意:上面命令中的-WhatIf常用参数是预览操作。-WhatIf 一旦您确定该操作将执行您想要的操作,请删除。

有关与上述运算符一起使用的正则表达式-match的说明,请参阅此 regex101.com 页面[1]

上面使用两个捕获组 ( ) 来捕获感兴趣的子字符串, (...)可以通过索引1自动变量访问。2$Matches

-f,然后使用格式运算符从捕获的子字符串中构建输出文件名。根据需要调整 LHS 格式字符串。

感谢-WhatIf,您将看到如下输出,这是您删除时会发生什么的预览- 请注意路径-WhatIf中的新文件名:Destination:

What if: Performing the operation "Rename File" on target 
"Item: /tmp/__XXXXXXXX_XXX_XXXXXXX_XXXX_XXXXX_XXXX XXX_Aircraft 017_XXXXXXXX-XXXXXXX_XXXXXXX-XXXXXXX-XXXXXX-01Apr2021-XXXXX
Destination: /tmp/Aircraft 017 - 01Apr2021".

请注意 脚本块( { ... }) 如何作为参数传递给Rename-Item-NewName参数,然后通过自动$_变量作用于每个输入文件并输出参数值以用于手头的输入对象。这样的脚本块称为延迟绑定脚本块


[1] 请注意,尽管regex101.com是一个用于可视化、解释和试验正则表达式的网站,它不支持 PowerShell 使用的.NET正则表达式引擎,但选择类似的引擎(例如 Java 的引擎)通常会表现出相同的行为,至少从根本上说。


推荐阅读