我怎样才能重新编号很多文件?
How can I renumber lots of files?
当前状态
我有一个编号的文件列表。这是一个例子(现实中还有很多文件):
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
?或者,也许我必须以某种方式将其重写为一个循环,以便能够在每次重命名后递增它?
我想说一个快速简单的方法是:
$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
您可以将 foreach 与替换和简单的正则表达式结合使用...
另外如果你想在数字之前保留第一个文件 0,比如 01/02/03 直到 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++
}
请注意,您可以使用范围通配符:
Get-ChildItem '[0-9][0-9] *.sql'
如果你真的想这样做,你可以尝试确定变量的范围:
Rename-Item -NewName {$_.Name -replace '[0-9][0-9] ', "$x "; $global:x++} -whatif
在脚本中使用脚本而不是全局。
总结几个技巧:
- 由于 Rename-Item 接受流水线输入,因此无需使用 foreach 进行迭代。
- 将
Get-ChildItem
放在 parentheses 中以先执行它,而不会因更改内容而受到破坏。
- 使用 wildcard/range 到 select 旧号码
- 用插入符号将替换正则表达式锚定在名称的开头
^
- 插入新号码时使用-f format operator强制两个地方
- 使用
$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
当前状态
我有一个编号的文件列表。这是一个例子(现实中还有很多文件):
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
?或者,也许我必须以某种方式将其重写为一个循环,以便能够在每次重命名后递增它?
我想说一个快速简单的方法是:
$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
您可以将 foreach 与替换和简单的正则表达式结合使用...
另外如果你想在数字之前保留第一个文件 0,比如 01/02/03 直到 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++
}
请注意,您可以使用范围通配符:
Get-ChildItem '[0-9][0-9] *.sql'
如果你真的想这样做,你可以尝试确定变量的范围:
Rename-Item -NewName {$_.Name -replace '[0-9][0-9] ', "$x "; $global:x++} -whatif
在脚本中使用脚本而不是全局。
总结几个技巧:
- 由于 Rename-Item 接受流水线输入,因此无需使用 foreach 进行迭代。
- 将
Get-ChildItem
放在 parentheses 中以先执行它,而不会因更改内容而受到破坏。 - 使用 wildcard/range 到 select 旧号码
- 用插入符号将替换正则表达式锚定在名称的开头
^
- 插入新号码时使用-f format operator强制两个地方
- 使用
$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