0

当前状态

我有一个编号的文件列表。这是一个示例(实际上有更多文件)

01 File.sql
02 File.sql
02 another_file.sql
02 a_third_file.sql
03 File.sql
04 File.sql
.....

期望的结果

如您所见,文件已编号,但有些文件的编号相同。我想要做的是遍历它们并重新编号以使列表看起来像这样:

01 File.sql
02 File.sql
03 another_file.sql
04 a_third_file.sql
05 File.sql
06 File.sql
07 File.sql
.....

我试过的

我想出了这个最有效的powershell脚本:

$x = 1
Get-ChildItem "*.sql" | Rename-Item -NewName {$_.Name -replace '[0-9][0-9] ', "$x "}

该脚本的作用是遍历所有文件并删除它们的当前编号并将其替换为我存储在$x. 到目前为止,我的脚本的唯一错误是所有文件都获得了数字1,因为我没有在任何地方增加它。

所以对于实际的问题

在我的脚本中我可以在哪里增加$x?或者也许我必须以某种方式将其重写为循环才能在每次重命名后增加它?

4

4 回答 4

2

我想说一个快速简便的方法是:

$x = 0
foreach ( $item in $( Get-ChildItem "PATH" "*.txt" ) ){
    $x++
    Rename-Item $item.fullName -newname $( $item.Name -replace '[0-9][0-9] ', "$x " )
}

但是,这不会执行错误检查,因此如果文件名已经存在,那么该项目将出错。

如果遇到任何错误,也许会进行两次扫描?或者在 $x++ 之后加入一个 IF ( Test-Path ...)

*编辑 - 将 $x 更改为 0,因此第一个重命名为 1

于 2019-05-15T13:55:18.287 回答
1

您可以将 foreach 与替换和简单的正则表达式一起使用...如果您想在 01/02/03 等数字之前将第一个文件保留为 0 直到 10,我为此添加了一条if语句...希望它有所帮助

$i = 1
foreach ($file in Get-ChildItem C:\targetPath) # Change to valid path
{
    if ($i -lt 10) {
    Rename-Item $file.FullName -NewName "0$i $($file.BaseName -replace '^\d+\s').sql"
    }

    else {
    Rename-Item $file.FullName -NewName "$i $($file.BaseName -replace '^\d+\s').sql"
    }
$i++
}
于 2019-05-15T14:08:11.810 回答
0

总结几个技巧:

  • 由于Rename-Item接受流水线输入,因此无需使用 foreach 进行迭代。
  • 将括号Get-ChildItem放在括号中以首先执行它,并且不会因更改内容而受到破坏。
  • 使用通配符/范围来选择旧号码
  • 用插入符号将替换正则表达式锚定在名称的开头^
  • 插入新数字时使用-f 格式运算符强制两个位置
  • 使用$script:x/$global:x更新重命名{script block} about_scopes中的变量
    $x = 1
    (Get-ChildItem "[0-9][0-9] *.sql") | 
        Rename-Item -NewName {$_.Name -replace '^\d{2}', ("{0:D2}" -f $global:x++} -WhatIf

如果输出看起来正常,请删除尾随-WhatIf

于 2019-05-15T18:26:49.207 回答
0

请注意,您可以使用范围通配符:

 Get-ChildItem '[0-9][0-9] *.sql'

如果您真的想这样做,您可以尝试确定变量的范围:

 Rename-Item -NewName {$_.Name -replace '[0-9][0-9] ', "$x "; $global:x++} -whatif

在脚本中使用脚本而不是全局。

于 2019-05-15T14:33:05.607 回答