我需要重命名许多包含姓名和徽章号码的文件。
这些文件如下所示:“John Doe 1234.txt”,我必须将其重命名为 1234.txt
(新文件必须仅包含徽章编号)。
此外,徽章编号不固定,可能包含 3-4 个数字。
更新:文件名包含 2-3 个以空格分隔的名称。例如:“John Doe 123.txt”或“John Junior Doe 1234.txt”
我本来想删除名称中的所有字母和空格,只保留数字,但我对 Powershell 不够了解。
谁能帮我吗?
答案1
文件名不能包含特殊字符( 该代码现在是万无一失的。/\:*?"<>|
),但可能包含%
和等字符,!
这可能会导致cmd.exe
误解,因此该代码并不万无一失。
@echo off
SETLOCAL ENABLEDELAYEDEXPANSION
set "dir=YOUR DIRECTORY HERE"
set "_output="
set "map=0123456789"
pushd "%dir%"
FOR %%a in (*.txt) do (
SETLOCAL
set "file=%%~na"
1>temp.log echo(!file!
for %%b in (temp.log) do set /A len=%%~zb-2
del /F /Q temp.log
for /L %%A in (0 1 !len!) do (
for /F "delims=*~ eol=*" %%? in ("!file:~%%A,1!") do if "!map:%%?=!" NEQ "!map!" set "_output=!_output!%%?"
)
ren "!file!.txt" "!_output!.txt"
ENDLOCAL
)
ENDLOCAL
笔记:最多只能处理 31 个文件,因为 我的假设是错误的。由于和的配对,它可以处理无限的SETLOCAL
SETLOCAL
文件ENDLOCAL
。
答案2
答案3
假设所有输入文件都以空格结尾,然后至少有一个数字,这看起来像是完成工作的另一种方法。但它不会检查重复的数字。[咧嘴笑]
它能做什么 ...
- 定义源目录和目标目录
我总是担心破坏原始文件,所以这个复制它们代替重命名它们.如果您想直接执行此操作,请将 替换Copy-Item
为Rename-Item
。
当您准备好进行实际操作时, 创建一些测试目录和文件并删除整个区域。- 定义要抓取的文件类型
- 获取符合过滤器的文件
- 删除所有
.BaseName
属性不以空格和至少一个数字结尾的 文件 - 在空格上拆分
.Basename
并获取结果中的最后一项 - 将 prop添加
.Extension
到上面 - 建立新的完整文件名
- 将旧的完整文件名复制到新的完整文件名
- 该
-PassThru
行将Copy-Item
“创建文件”信息发送到屏幕
代码 ...
$SourceDir = "$env:TEMP\InFiles"
$DestDir = "$env:TEMP\OutFiles"
#region >>> make some test dirs & files
$SourceDir, $DestDir |
ForEach-Object {
$Null = mkdir -Path $_ -ErrorAction 'SilentlyContinue'
}
# the last file is not to be worked on - wrong pattern
@'
FName LName 1234.txt
Alfa Bravo Charlie 89.txt
First Middle Last 666.txt
Wiki Tiki Exotica Music.txt
'@ -split [System.Environment]::NewLine |
ForEach-Object {
$Null = New-Item -Path $SourceDir -Name $_ -ItemType 'File' -ErrorAction 'SilentlyContinue'
}
#endregion >>> make some test files
$Filter = '*.txt'
Get-ChildItem -LiteralPath $SourceDir -Filter $Filter -File |
Where-Object {
# filter out any basename that does NOT end with a space followed by at least one digit
$_.BaseName -match ' \d{1,}$'
} |
ForEach-Object {
# split on the spaces & take the last item from the resulting array
$NewBaseName = $_.BaseName.Split(' ')[-1]
$NewFileName = '{0}{1}' -f $NewBaseName, $_.Extension
$FullNewFileName = Join-Path -Path $DestDir -ChildPath $NewFileName
Copy-Item -LiteralPath $_.FullName -Destination $FullNewFileName -PassThru
}
答案4
您可以使用以下方法通过批处理文件执行此操作。
无论开头有多少个字母和空格,这都可以起作用。
@echo off
setlocal enabledelayedexpansion
set "fPath=C:\test\my files\"
:: For each .txt file found in path %fPath% do....
for /F "tokens=*" %%a in ('DIR /B /ON "%fPath%*.txt"') do (
echo Processing: %%a
set "oName=%%a"
set "fName=%%a"
call :loop
)
echo Finished
endlocal
pause
:eof
exit /B
::=====================================================================
:: Check if the name is only numbers plus ".txt" on the end and if not, then remove the first character and check again.
:: If only numbers remaining, rename the original file. If no characters left then no match found and should go to next file.
:loop
if "!fName!"==".txt" exit /B
echo !fName!|findstr /r /c:"^[0-9]*\.txt$">nul
if !errorlevel! NEQ 0 set "fName=!fName:~1!" && goto :loop
ren "%fPath%%oName%" !fName!
exit /B