使用PowerShell批量复制和重命名文件

时间:2017-02-09 02:11:47

标签: powershell

我正在尝试使用PowerShell批量复制和重命名文件。

原始文件名为AAA001A.jpg,AAB002A.jpg,AAB003A.jpg等。

我想通过剥离文件名中的前四个字符和句点之前的字符来复制带有新名称的文件,以便复制的文件名为01.jpg,02.jpg,03.jpg等等。

我在Linux上有使用Bash脚本的经验,但我很难知道如何使用PowerShell执行此操作。经过几个小时的反复试验,这就像我得到的那样接近:

Get-ChildItem AAB002A.jpg | foreach { copy-item $_ "$_.name.replace ("AAB","")" }

(它不起作用)

4 个答案:

答案 0 :(得分:0)

不是Powershell,而是批处理文件:

(因为有人想对评论过于迂腐)

df

date       AB   CD
2016-01-01  a    1
2016-01-02  a    3
2016-01-03  a    5

答案 1 :(得分:0)

在Powershell中:
(没有讨厌的正则表达式。我们讨厌正则表达式!我们这样做!)

Get-ChildItem *.jpg | Copy-Item -Destination {($_.BaseName.Substring(4) -replace ".$")+$_.Extension} -WhatIf

有关表达的详细信息:

$_.BaseName.Substring(4)  :: Chop the first 4 letters of the filename.
-replace ".$"             :: Chop the last letter.
+$_.Extension             :: Append the Extension

答案 2 :(得分:0)

注意:
*虽然可能比abelenky's answer稍微复杂一点,但它(a)更加健壮,因为它确保只处理符合所需模式的*.jpg个文件,(b)显示一些高级正则表达式技术,( c)提供背景信息并用OP的方法解释问题 *此答案使用 PSv3 + 语法 功能

Get-ChildItem *.jpg |
  Where-Object Name -match '^.{4}(.+).\.(.+)$' | 
    Copy-Item -Destination { $Matches.1 + '.' + $Matches.2 } -WhatIf

要使命令保持简短,不会显式控制目标目录,因此副本将放在当前目录中。确保放置在同一个目录中。作为输入文件,请使用
Join-Path $_.PSParentPath ($Matches.1 + '.' + $Matches.2)内的{ ... }

-WhatIf 预览将复制到哪些文件;将其删除以执行实际复制。

  • Get-ChildItem *.jpg输出所有*.jpg个文件 - 无论它们是否适合要重命名的文件模式。

  • Where-Object Name -match '^.{4}(.*).\.(.+)$'然后使用正则表达式(正则表达式)将匹配缩小到适合模式的匹配:

    • ^...$锚定正则表达式以确保它与整个输入匹配(^匹配输入的开头,$结束。
    • .{4}与第一个4字符(.)匹配,无论它们是什么。
    • (.+)匹配任何非空字符序列,并且由于被(...)括起来,会捕获捕获组中的序列,这反映在自动{{1>}中1}}变量,可以$Matches访问(由于是第一个捕获组)。
    • $Matches.1匹配文件扩展名之前的字符。
    • .文字 \.匹配,原因是.转义,即扩展的开始。
    • \是捕获文件扩展名的第二个捕获组(没有前面的(.+)文字),可以.访问。
  • $Matches.2然后根据从输入文件名中提取的捕获组值重命名每个输入文件。

    • 通常,出于性能原因,直接管道到cmdlet(如果可行)总是优于管道Copy-Item -Destination { $Matches.1 + '.' + $Matches.2 } cmdlet(其内置别名为Foreach-Object)。
      在上面的foreach命令中,目标路径是通过 script-block参数指定的,该参数是针对每个输入路径计算的,其中Copy-Item绑定到手头的输入文件。

    • 注意:以上假设副本应放在当前目录中,因为脚本块只输出文件名,而不是路径

      • 要明确控制目标路径,请在$_脚本块中使用Join-Path 例如,要确保副本始终与输入文件放在同一文件夹中 - 无论当前目录是什么。是 - 使用:
        -Destination

至于您尝试过的内容

  • Join-Path $_.PSParentPath ($Matches.1 + '.' + $Matches.2)内(双引号字符串),您必须使用{{1>},子表达式运算符,才能嵌入应替换为其表达式的表达式值。

  • 无论如何,"..."(a)由于空格char而在语法上断开。在$(...)之前(您是否将.replace ("AAB", "")类型的( 方法与PowerShell的[string] 运算符<混淆了/ em>?),(b)硬编码要删除的前缀,(c)仅限于 3 个字符,(d)在句点之前不删除该字符。 / p>

  • 目标位置警告也适用:如果您的表达式有效,它只会计算为文件名,这会将生成的文件放在当前目录而不是与输入文件相同的目录(如果从当前目录运行命令,或者如果这是您的实际意图,那么这不会有问题。)

答案 3 :(得分:-1)

试试这个:

Get-ChildItem "C:\temp\Test" -file -filter "*.jpg" | where BaseName -match '.{4,}' | 
    %{ Copy-Item $_.FullName  (Join-Path $_.Directory  ("{0}{1}" -f  $_.BaseName.Substring(4, $_.BaseName.Length - 5), $_.Extension))    }