Войти

Показать полную графическую версию : Массовое переименование файлов со счётчиком.


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

Iska
24-10-2020, 17:27
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
@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
И Вы ничего не сказали, что делать, если там уже окажутся файлы с такими «нумерованными» именами. »
переименовать всё.

serg515
24-10-2020, 23:53
@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
serg515, можно ещё однострочник PS попробовать:
dir *.txt | % {$i=1} {ren $_ -NewName ("{0:D1}.txt" -f $i++)}

serg515
25-10-2020, 13:52
dir *.txt | % {$i=1} {ren $_ -NewName ("{0:D1}.txt" -f $i++)} »
к сожалению если существуют файлы с такими числовыми имена возникает ошибка

megaloman
25-10-2020, 14:11
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
…переименовывать дважды. »
Ну, можно ещё сначала переместить во временный каталог, а затем перемещать по одному в другой временный каталог, там переименовывать в очередное имя, а затем перемещать вобрат в исходное местоположение, и в конце удалять оба уже пустых временных каталога — это гарантирует отсутствие проблем с наложением имён даже без проверки. Но тут надо смотреть — не потеряются ли разрешения безопасности на файлы.

megaloman
25-10-2020, 16:27
оба уже пустых временных каталога »ИМХО, слишком много временных каталогов, хватает одного.@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
megaloman, а, ну да — можно сразу туда.

Кстати, в vbs пришлось делать именно Move, переименовать файл я не умею. »
Например:
objFile.Name = strNewName
В самой библиотеке ошибка в описании, что данное свойство только для чтения:
Property Name As String

Get name of file

megaloman
25-10-2020, 22:11
Iska, Вы правы, почему-то ранее я об это спотыкался, пробовал и у меня не получалось. 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
$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"
})




© OSzone.net 2001-2012