이름과 배지 번호가 포함된 많은 파일의 이름을 변경해야 합니다.
파일은 "John Doe 1234.txt"와 같으며 이름을 1234.txt로 바꿔야 합니다
(새 파일에는 배지 번호만 포함되어야 함).
또한 배지 번호는 고정되어 있지 않으며 3~4개의 숫자를 포함할 수 있습니다.
업데이트: 파일 이름에는 공백으로 구분된 2-3개의 이름이 포함되어 있습니다. 예: "John Doe 123.txt" 또는 "John 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
하고 결과의 마지막 항목을 가져옵니다. .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