Ich muss viele Dateien umbenennen, die einen Namen und eine Dienstnummer enthalten.
Die Dateien sehen so aus: „John Doe 1234.txt“ und ich muss sie in 1234.txt umbenennen
(die neue Datei darf nur die Dienstnummer enthalten).
Auch die Dienstnummer ist nicht festgelegt, sie könnte 3-4 Zahlen enthalten.
Update: Der Dateiname enthält 2-3 Namen, die durch Leerzeichen getrennt sind. Beispiel: „John Doe 123.txt“ oder „John Junior Doe 1234.txt“
Ich hatte überlegt, alle Buchstaben und Leerzeichen aus dem Namen zu löschen und nur die Zahlen zu behalten, aber ich kenne mich mit Powershell nicht gut genug aus.
Kann mir jemand helfen?
Antwort1
Dateinamenkann nichtenthalten Sonderzeichen ( ), können aber auch Zeichen wie und DER CODE IST JETZT NARRENSICHER./\:*?"<>|
enthalten , die zu fehlerhaftem Abfangen führen können , der Code ist also nicht narrensicher.%
!
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
Notiz: kann nur bis zu 31 Dateien verarbeiten, da MEINE ANNAHME WAR FALSCH.Es kann aufgrund der gepaarten SETLOCAL
SETLOCAL
und eine unendliche Anzahl von Dateien verarbeiten ENDLOCAL
.
Antwort2
Vorausgesetzt, alle Dateinamen sind im Format "Vorname Nachname Zahl.txt
Du kannst rennen:
pushd "C:\Temp\su\"
dir | ? { $_.Name -like "*.txt" } |
% { Rename-Item $_ "$($_.BaseName.split(' ')[2])$($_.Extension)" }
popd
Ändern Sie die erste Zeile so, dass sie Ihrem Pfad entspricht. (fügen Sie den gesamten Ausschnitt ein und drücken Sie zweimal die Eingabetaste)
Antwort3
vorausgesetzt, alle Eingabedateien enden mit einem Leerzeichen und dann mindestens einer Ziffer, sieht dies wie eine weitere Möglichkeit aus, die Aufgabe zu erledigen. Es erfolgt jedoch KEINE Überprüfung auf doppelte Zahlen. [Grinsen]
Was es macht ...
- definiert die Quell- und Zielverzeichnisse.
Ich bin immer nervös, wenn es darum geht, die Originaldateien zu überschreiben.kopiert sieanstattUmbenennen. wenn Sie es direkt tun möchten, ersetzen Sie dasCopy-Item
durchRename-Item
. - Erstellt einige Testverzeichnisse und -dateien und
entfernt den gesamten Bereich, wenn Sie bereit sind, die Dinge wirklich anzugehen. - definiert den zu erfassenden Dateityp
- ruft die Dateien ab, die dem Filter entsprechen
- entfernt alle Dateien, deren
.BaseName
Eigenschaften NICHT mit einem Leerzeichen und mindestens einer Ziffer enden - teilt die
.Basename
in die Leerzeichen und greift das letzte Element in den Ergebnissen - fügt die
.Extension
Stütze zu den oben genannten hinzu - baut dieneuvollständiger Dateiname
- kopiert den ALTEN vollständigen Dateinamen in den NEUEN vollständigen Dateinamen
- die
-PassThru
on-theCopy-Item
-line sendet "Datei erstellt"-Informationen an den Bildschirm
der Code ...
$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
}
Antwort4
Sie können dies mit einer Batchdatei mithilfe der folgenden Methode tun.
Dies funktioniert unabhängig davon, wie viele Buchstaben und Leerzeichen am Anfang stehen.
@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