Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Скриптовые языки администрирования Windows (http://forum.oszone.net/forumdisplay.php?f=102)
-   -   Массовое переименование файлов со счётчиком. (http://forum.oszone.net/showthread.php?t=346809)

serg515 24-10-2020 16:28 2937422

Массовое переименование файлов со счётчиком.
 
Есть большое количество текстовых файлов в папке.
Как лучше и быстрее переименовать такое кол-во файлов средствами .vbs
Можно и .bat, но первое вроде бы быстрее работает.
Чтобы новые имена были от 1 и выше,в формате с одной цифрой.(т.е. не 01,или 001, а 1).

Iska 24-10-2020 17:27 2937423

serg515, вообще, подобные одноразовые вещи быстрее и проще делать полуавтоматически либо сторонними файловыми менеджерами, либо специализированными средствами.

Цитата:

Цитата serg515
Можно и .bat, но первое вроде бы быстрее работает. »

Да нет, в данном случае особой разницы Вы не увидите.
Скрытый текст
Код:

@echo off
setlocal enableextensions enabledelayedexpansion

set /a iCount = 0
for /f "usebackq delims=" %%i in (`dir /b /a:-d "*.txt"`) do (
        set /a iCount += 1
        ren "%%~i" "!iCount!%%~xi"
)

endlocal
exit /b 0


Другое дело, что в именах файлов могут встретиться символы, которые окажутся не по зубам такому пакетному файлу. Посему — да, можно и WSH/PoSH:
Скрытый текст
Код:

Get-ChildItem -Path '*.txt' | ForEach-Object -Begin {
        $iCount = 0
    } -Process {
        Rename-Item -Path $_.FullName -NewName "$((++$iCount))$($_.Extension)"
    }


И Вы ничего не сказали, что делать, если там уже окажутся файлы с такими «нумерованными» именами.

megaloman 24-10-2020 17:41 2937426

Код:

@Echo Off
        Set "BoxIn=Z:\Soft_In"
        Set "Mask=*.txt"
        For %%i In ("%BoxIn%\%Mask%") Do (Set "Ext=%%~xi" &Ren "%%i" "%%~nxi.~~tmp~~")

        Set /A N=0
        For %%i In ("%BoxIn%\*%Ext%.~~tmp~~") Do (
                Set /A N+=1 &Call Ren "%%i" "%%N%%%Ext%"
        )
Exit /B

И всё равно, были ли там нумерованные имена или нет, все переименуем заново.

serg515 24-10-2020 18:05 2937427

Цитата:

Цитата Iska
И Вы ничего не сказали, что делать, если там уже окажутся файлы с такими «нумерованными» именами. »

переименовать всё.

serg515 24-10-2020 23:53 2937458

Цитата:

Цитата megaloman
@Echo Off
Set "BoxIn=Z:\Soft_In"
Set "Mask=*.txt"
For %%i In ("%BoxIn%\%Mask%") Do (Set "Ext=%%~xi" &Ren "%%i" "%%~nxi.~~tmp~~")
Set /A N=0
For %%i In ("%BoxIn%\*%Ext%.~~tmp~~") Do (
Set /A N+=1 &Call Ren "%%i" "%%N%%%Ext%"
)
Exit /B »

работает.по времени похоже на total commander.
может есть аналогичное в vbs ?

Uragan66 25-10-2020 09:06 2937473

serg515, можно ещё однострочник PS попробовать:
Код:

dir *.txt | % {$i=1} {ren $_ -NewName ("{0:D1}.txt" -f $i++)}

serg515 25-10-2020 13:52 2937511

Цитата:

Цитата Uragan66
dir *.txt | % {$i=1} {ren $_ -NewName ("{0:D1}.txt" -f $i++)} »

к сожалению если существуют файлы с такими числовыми имена возникает ошибка

megaloman 25-10-2020 14:11 2937515

vbs
Код:

MyDir = "Z:\Soft_In"
Ext = "txt"

MyMask = "^.*\." + Ext + "$"

Set Reg = CreateObject("VBScript.RegExp")
Reg.IgnoreCase = True
Reg.Pattern = MyMask

With CreateObject("Scripting.FileSystemObject")
    Set Files = .GetFolder(MyDir).Files

    For Each File In Files
        FilePath = File.Path
        If Reg.Test(FilePath) Then
            .MoveFile FilePath, FilePath + ".~~~tmp~~~"
        End If
    Next

    Set Files = .GetFolder(MyDir).Files
    Reg.Pattern = "^.*\.~~~tmp~~~$"

    N = 0
    For Each File In Files
        FilePath = File.Path
        If Reg.Test(FilePath) Then
            N = N + 1
            .MoveFile FilePath, File.ParentFolder + "\" + CStr(N) + "." + Ext
        End If
    Next
End With

MsgBox "Done"

В ~2раза быстрее моего CMD. Переименовываю все файлы с указанным расширением. Если бы была гарантия, что все исходные файлы если и имеют цифровые имена, но более числа файлов, то переименование можно было бы сделать еще в 2 раза быстрее. В противном случае вижу только такое решение, реализованное в моих CMD и VBS: переименовывать дважды.

Iska 25-10-2020 15:52 2937522

Цитата:

Цитата megaloman
…переименовывать дважды. »

Ну, можно ещё сначала переместить во временный каталог, а затем перемещать по одному в другой временный каталог, там переименовывать в очередное имя, а затем перемещать вобрат в исходное местоположение, и в конце удалять оба уже пустых временных каталога — это гарантирует отсутствие проблем с наложением имён даже без проверки. Но тут надо смотреть — не потеряются ли разрешения безопасности на файлы.

megaloman 25-10-2020 16:27 2937524

Цитата:

Цитата Iska
оба уже пустых временных каталога »

ИМХО, слишком много временных каталогов, хватает одного.
Код:

@Echo Off
        Set "BoxIn=Z:\Soft_In"
        Set "Mask=*.txt"

        Set "MyTMP=%BoxIn%\%~nx0.tmp"
       
        2>nul Rd /Q /S "%MyTMP%"
        Md "%MyTMP%"       

        Set /A N=0
        For %%i In ("%BoxIn%\%Mask%") Do (Set /A N+=1 &>nul Call Move "%%i" "%MyTMP%\%%N%%%%~xi")

        >nul Move "%MyTMP%\*.*" "%BoxIn%\"
        Rd /Q /S "%MyTMP%"
Exit /B

Я раньше тоже предполагал такой вариант, решил, что он будкт медленнее, но по времени одно и то же.
Кстати, в vbs пришлось делать именно Move, переименовать файл я не умею.

Iska 25-10-2020 21:24 2937538

megaloman, а, ну да — можно сразу туда.

Цитата:

Цитата megaloman
Кстати, в vbs пришлось делать именно Move, переименовать файл я не умею. »

Например:
Код:

objFile.Name = strNewName
В самой библиотеке ошибка в описании, что данное свойство только для чтения:
Цитата:

Property Name As String

Get name of file

megaloman 25-10-2020 22:11 2937543

Iska, Вы правы, почему-то ранее я об это спотыкался, пробовал и у меня не получалось.
vbs c переименованием
Код:

MyDir = "Z:\Soft_In"
Ext = "txt"

MyMask = "^.*\." + Ext + "$"

Set Reg = CreateObject("VBScript.RegExp")
Reg.IgnoreCase = True
Reg.Pattern = MyMask

With CreateObject("Scripting.FileSystemObject")
    Set Files = .GetFolder(MyDir).Files

    For Each File In Files
        Filename = File.Name
        If Reg.Test(Filename) Then
            File.Name = Filename + ".~~~tmp~~~"
        End If
    Next

    Reg.Pattern = "^.*\.~~~tmp~~~$"

    N = 0
    For Each File In Files
        Filename = File.Name
        If Reg.Test(Filename) Then
            N = N + 1
            File.Name = CStr(N) + "." + Ext
        End If
    Next
End With

MsgBox "Done"


greg zakharov 25-10-2020 22:22 2937545

Код:

$g = Get-ChildItem X:\path\*.txt | Group-Object {!($_.Basename -as [UInt32])}
[Linq.Enumerable]::Zip([String[]]($g[1].Group.FullName), [UInt32[]](
  (1..$g.Group.Length).Where{$g[0].Group.Basename -notcontains $_}
), [Func[String, UInt32, ScriptBlock]]{
  Rename-Item $($args[0])" "$($args[1]).txt"
})



Время: 10:23.

Время: 10:23.
© OSzone.net 2001-