1

Тема: перейменувати групу файлів по масці

Доброго дня, спільното.
Підкажіть будь-ласка, як можна перейменувати групу файлів в одній папці. а точніше видалити певці символи в імен файлів
до прикладу, є такі файли

11111-81.jpg
11112-82.jpg
11113-86.jpg
11114-79.jpg
11115-(81).jpeg
11116-(81).jpeg
11117-90.jpeg

чи можливо командою rename зробити ось так:
11111.jpg
11112.jpg
11113.jpg
11114.jpg
11115.jpeg
11116.jpeg
11117.jpeg
пробую ось так

rename "*-???.*" "*////.*"

пише що помилка

заздалегідь дякую за відповідь

2

Re: перейменувати групу файлів по масці

Знаю що в Microsoft PowerToys є інструмент для масового перейменування
https://learn.microsoft.com/windows/powertoys/powerrename

Подякували: colin200x, mikeos2

3 Востаннє редагувалося colin200x (20.11.2024 16:13:05)

Re: перейменувати групу файлів по масці

так є, я вже ним корустуюсь, яле не розумію як в ньому забрати лишні символи іменно в кінці імені файлу. бо файлів декілька десятків тисяч.

4 Востаннє редагувалося javascriptIsLife (20.11.2024 23:47:32)

Re: перейменувати групу файлів по масці

Написав програмку на VBScript. Не перейменовує файли в підкаталогах. Змінює назву файлів таким чином що видаляється рядок символів що починається з - і закінчується . По задумці має виходити так: 11115-(81)-aa13.jpeg -> 11115.jpeg. Запускати на свій страх. Файли копіюються з новими назвами з одного каталогу до іншого.

  • Копіюєш текст нижче в текстовий редактор і зберігаєш в файлі з будь–якою назвою.

  • В каталозі зі збереженим файлов відриваєш вікно cmd.exe і пишеш там cscript.exe massrname.vbs /folder:"d:\mass" /d:"c:\dd" та тиснеш клавішу Enter. massrename.vbs треба замінити на назву файлу в якому було збережоно наведений нижче текст а d:\mass на шлях до каталогу з файлами які треба перейменувати. c:\dd замінюш на шлях до каталогу куди будуть копіюватися файли з новими назвами. Шляхи до каталогів мають бути в лапках.

Dim objRegExp
Set objRegExp = CreateObject("VBScript.RegExp")
With objRegExp
    .IgnoreCase = True
    .Pattern = "-.+\."
End With

Dim obj_shell
Set obj_shell = CreateObject("WScript.Shell")

Dim oFSO
Set oFSO = CreateObject("Scripting.FileSystemObject")

Dim oFolder

Set oFolder = oFSO.GetFolder(WScript.Arguments.Named("folder"))

Dim d
d = WScript.Arguments.Named("d")

Dim oMatches
For Each oFile In oFolder.Files
        Set oMatches = objRegExp.execute(oFile.Name)
        If oMatches.count > 0 Then
            Dim m
            m = d & "\" & Replace(ofile.Name, oMatches.item(0), ".")
            WScript.Echo ofile.Name & " -> " & m
            oFSO.CopyFile ofile.Path, m
        End If
Next
' Beep
WScript.StdOut.Write Chr(7)
Подякували: colin200x1

5 Востаннє редагувалося mikeos (21.11.2024 01:36:24)

Re: перейменувати групу файлів по масці

Думаю найпростіше через PowerToys.
Також можна в PowerShell за допомогою Get-ChildItem + Rename-Item + регулярні вирази.
Наприклад:

Get-ChildItem -File | Rename-Item -NewName { $_.Name -replace '^(\d+)(-.+)(\..+)$', '$1$3' }

Або рекурсивної і з фільтром по файлах:

Get-ChildItem -Recurse -File | Where { $_.Name -match '^(\d+)(-.+)(\.jpe?g)$' } | Rename-Item -NewName { $_.Name -replace '^(\d+)(-.+)(\..+)$', '$1$3' }

Не перевіряв, але можна поекспериментувати )

Подякували: colin200x1

6

Re: перейменувати групу файлів по масці

всім дякую за допомогу, попробую скрипт і команди!

7

Re: перейменувати групу файлів по масці

Я б спробував зробити все в cmd.exe, але незовсім по масці. Якщо в нас усі імена файлів являють собою п'ятицифрове число від 11111 до 11117, з відокремленою дефісом додатковою інформацією після нього (яку треба викинути) і розширенням (яке треба зберегти), то можна зробити так:

for /L %i in (11111 1 11117) do for %j in (%i-*) do ren %j %i%~xj

Але якщо замість чисел в основній частині будуть літери, то подібний підхід не спрацює. Якщо деякі з цих чисел починаються на 0, 00 і т.д., то з кожною серією початкових нулів треба працювати окремо:

:: Перейменувати 00100...00999-*.*:
for /L %i in (100 1 999) do for %j in (00%i-*) do ren %j 00%i%~xj
:: Перейменувати 01000...09999-*.*:
for /L %i in (1000 1 9999) do for %j in (0%i-*) do ren %j 00%i%~xj
Подякували: leofun011

8

Re: перейменувати групу файлів по масці

P.Y. написав:

Я б спробував зробити все в cmd.exe...

Рекомендую познайомитись з PowerShell, набагто більше можливостей )

9

Re: перейменувати групу файлів по масці

У PS можливостей, може, й більше, але зроблені в абсолютно несумісний з CMD спосіб — фактично, це варіація на тему юніксових командних оболонок, доповнена ООП заради ООП. Шкода, що дрібном'які лінію CMD закинули, а розробники вільного ПЗ хіба що ДОСівський command.com переписати спромоглися.

10 Востаннє редагувалося mikeos (21.11.2024 20:54:11)

Re: перейменувати групу файлів по масці

P.Y. написав:

У PS можливостей, може, й більше, але зроблені в абсолютно несумісний з CMD спосіб — фактично, це варіація на тему юніксових командних оболонок, доповнена ООП заради ООП. Шкода, що дрібном'які лінію CMD закинули, а розробники вільного ПЗ хіба що ДОСівський command.com переписати спромоглися.

Ну так це добре коли одні беруть в інших якусь ідею/підхід який зручний/корисний. Чого вартий наприклад оператор "|", якого немає в cmd. І порівняно з юніксовими командами то cmd взагалі дуже бідний. А от PowerShell вже "потужний" інструмент ). Правда назви команд трохи може не звичні, в юнікс-системах вони більш лаконічні.

І наприклад в запропонованому вами варіанті з циклами - теоретично ітерацій більше ніж самих файлів, плюс вкладені цикли. А все через обмежені властивості cmd )

Подякували: leofun011

11

Re: перейменувати групу файлів по масці

mikeos написав:

Чого вартий наприклад оператор "|", якого немає в cmd

Шо?! Базові оператори перенаправлення потоків (>, <, |) були ще в ДОСівському command.com (зокрема, вони були необхідні для осмисленого користування командами sort i more), у віндовому cmd.exe додався паралелізм при їх обробці, а також допоміжні оператори для перенаправлення stderr та ін. — схоже, що значна частина «відсутнього» функціоналу cmd насправді є недовивченою.

Чого в cmd справді нема, а на юніксах є, так це FIFO — довільно створюваних потоків вводу-виводу, які можна підставляти в команди замість звичайних файлів. Чесно кажучи, не знаю, чи було цю концепцію втілено в PS, чи, можливо, для них потрібні глибші зміни в архітектурі ОС, що виходять за рамки можливостей інтерпретатора команд.

Подякували: leofun01, wander2

12

Re: перейменувати групу файлів по масці

mikeos написав:

І наприклад в запропонованому вами варіанті з циклами - теоретично ітерацій більше ніж самих файлів, плюс вкладені цикли. А все через обмежені властивості cmd )

Очікується, що вкладений цикл робитиме 0 або 1 ітерацію за раз. Якщо ітерацій 2 або більше, це означає, що в нас кілька файлів, яким присвоюється однакове нове ім'я — чого за умовами задачі не мало б бути.

Проблемою є не можливості cmd, а відсутність стандартної утиліти назразок sed (яка, взагалі-то, не є частиною командної оболонки — це окрема програма, і в юніксах також). Якщо встановлено sed з GnuWin32 (чи іншого порту юніксових утиліт), можна зробити так:

for /f "tokens=1,2" %i in ('"dir/b|sed 's/\([0-9a-zA-Z]*\)-[^^.]*\(.*\)/\0 \1\2/; / /!d'"') do ren %i %j

Добре, визнаю, це досить громіздко й неінтуїтивно, вимагає встановлення додаткової програми sed, і якщо цей код використовувати не безпосередньо в командному рядку, а в батнику, то його доведеться місцями переробити (як мінімум, позамінювати % на %% і, можливо, збільшити кількість ^). Але це не те, що cmd принципово не може робити через якусь свою обмеженість порівняно з bash.

Подякували: leofun011

13

Re: перейменувати групу файлів по масці

Те ж саме (cmd+sed), але трохи красивіше:

for /f "tokens=1,2" %i in ('"dir/b *-*.*|sed 's/\([^^-]*\)-[^^.]*\(.*\)/\0 \1\2/'"') do ren %i %j

Недоліком цієї та попередньої версії коду є те, що він несумісний з пробілами в іменах перейменовуваних файлів. Якщо в директорії є й такі файли, потрібен інший обмежувач імен у результатах пошуку (наприклад, двокрапка, що в іменах файлів не використовується):

for /f "tokens=1,2 delims=:" %i in ('"dir/b *-*.*|sed 's/\([^^-]*\)-[^^.]*\(.*\)/\0:\1\2/'"') do ren "%i" "%j"
Подякували: leofun011

14

Re: перейменувати групу файлів по масці

І ще трохи причешу свій код:

dir/b *-*.*|for /f "tokens=1,2 delims=:" %i in ('sed "s/\([^-]*\)-[^.]*\(.*\)/\0:\1\2/"') do ren "%i" "%j"

Пайп винесено за межі параметрів циклу, що дозволяє зменшити кількість лапок і використовувати нормальну кількість ^ у регексах.

15

Re: перейменувати групу файлів по масці

Здається, нарешті тепер оптимально:

dir/b *-*.*|for /f "tokens=1,2 delims=:" %i in ('sed "s/\([^-]*\)-.*/\0:\1/"') do ren "%i" "%j%~xi"

У попередніх версіях розширення вибиралось за допомогою регексів і робило це неправильно, якщо десь усередині імені була додаткова крапка. Тут розширення виділяється засобами самого cmd, що виправляє цю проблему й дозволяє зменшити регулярний вираз.

Подякували: leofun011

16

Re: перейменувати групу файлів по масці

Я часто використовую зв'язку cmd+sed, тому мої роздуми пішли шляхом, наведеним вище. Хоча насправді для цієї задачі нема потреби використовувати регулярні вирази — можна обійтися й примітивним поділом токенів, закладеним у можливості вбудованого циклу for. SED був потрібен як сокира в юшці з сокири, і після того, як до юшки було додано всі необхідні інгредієнти, ми її виймаємо, лишаючи чистий cmd:

for /f "tokens=1* delims=-" %i in ('dir/b *-*.*') do ren "%i-%j" "%i%~xj"