如何重新命名檔案 - 刪除名稱並保留編號

如何重新命名檔案 - 刪除名稱並保留編號

我需要重命名許多包含姓名和徽章編號的檔案。

這些檔案如下所示:“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

假設所有檔案名稱的格式為「First Last Number.txt

你可以運行:

pushd "C:\Temp\su\"
dir | ? { $_.Name -like "*.txt" } | 
% { Rename-Item $_ "$($_.BaseName.split(' ')[2])$($_.Extension)" }
popd

更改第一行以符合您的路徑。 (貼上整個片段並按 Enter 兩次)

顯示開始檔案名稱、命令和結果的螢幕截圖。

答案3

假設所有輸入檔都以空格結尾,然後至少有一個數字,這看起來是完成這項工作的另一種方法。不過,它不會檢查重複號碼。 [咧嘴笑]

它能做什麼 ...

  • 定義來源和目標目錄
    我總是對破壞原始檔案感到不安,所以這個複製它們代替重新命名它們。如果你想直接執行,請將 替換Copy-ItemRename-Item.
  • 建立一些測試目錄和文件,
    當您準備好真正做事情時,刪除整個區域。
  • 定義要抓取的文件類型
  • 取得與過濾器匹配的文件
  • .BaseName刪除props 不以空格和至少一位數字結尾 的所有文件
  • 拆分.Basename空格並取得結果中的最後一項
  • 將 prop加到.Extension上面
  • 建立新的完整檔案名稱
  • 將舊的完整檔名複製到新的完整檔名
  • 線路-PassThruCopy-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

相關內容