6

我在 PowerShell 中制作重命名脚本时遇到了很多麻烦。情况:在一个目录中,我有以以下格式命名的文件夹:“四位数字 - 文本 - 垃圾”我想将其重命名为“文本(四位数字)”

现在我已经创建了一个目录,其中包含一些示例名称可以使用:

1996 - 一些有趣的东西 - 一些糟糕的东西

2006 - 复制这个 - 忽略

我已经尝试设置一个脚本来回显他们的名字,但我不能完全掌握正则表达式的窍门。以下代码仅打印“1996 - something”和“2006 - copy”

Get-ChildItem | Foreach-Object { if ($_.BaseName -match "(\d{4} - \w+ -*)") { echo $matches[0]}}

这个将打印“1996 - 一些有趣的东西 - 一些糟糕的\n ()”和“2006 - 复制这个 - 忽略\n ()”

Get-ChildItem | Foreach-Object { echo ($_.BaseName -replace "(\d{4} - \w+ - *)"), "$2 ($1)"}

有人能告诉我为什么这两种方法都不尊重文字字符串“ - ”作为匹配的边界吗?

*编辑*感谢佳沛,解决我的问题的代码是

Get-ChildItem | Foreach-Object {
if ($_.BaseName -match "(\d{4} - [^-]*)") { 
  Rename-Item $_ ($_.BaseName -replace "(\d{4}) - (.+)(?= -).*" ,'$2 ($1)')
  }
}
4

2 回答 2

6

这对你有用吗:

Get-ChildItem | Foreach-Object { 
  if ($_.BaseName -match "(\d{4} - [^-]*)") { 
      echo $matches[0].TrimEnd()
    }
}

注意 TrimEnd - 这是在第二个破折号之前修剪尾随空格。

至于为什么您的示例不起作用: \w+ 匹配任何单词字符,因此它不会匹配“有趣的东西”内的空格。* 表示零个或多个。所以 -* 匹配零个或多个破折号,在你的情况下 - 零。

编写可能适合您的表达式的另一种方法是:

Get-ChildItem | Foreach-Object { 
  if ($_.BaseName -match "(\d{4} - .+(?= -))") { 
      echo $matches[0]
    }
}

其中(?= -)构造是肯定的前瞻断言 在这种情况下,您不需要在末尾修剪额外的空间,因为它在正则表达式本身中已经说明。

更新 1

修改为进行转换:

gci | %{ $_.BaseName -replace "(\d{4}) - (.+)(?= -).*" ,'$2 ($1)' }
于 2013-06-04T22:44:56.917 回答
1

尝试这个:

Get-ChildItem | 
    Select-String -Pattern '(\d{4})\s+-\s+(\w+(\s+\w+)*)\s+-.*' |
    Foreach-Object { "$($_.Matches.Groups[2].Value) ($($_.Matches.Groups[1].Value))" }
于 2013-06-06T00:19:56.283 回答