Компьютерный форум 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=294109)

deniskx 18-01-2015 19:23 2457990

Переименовать файл по содержимому
 
Приветствую. Помогите, пожалуйста, я не спец.
Есть очень много файлов default.htm, каждый лежит в своей папке. Это html страницы, внутри у каждой из них есть тэг <title>Название страницы</title>. Как бы переименовать каждый файл default.htm в Название страницы.html ? Повторюсь, каждый в своей папке, так что пересечений не будет.

И еще в названии страницы присутствует символ / (например русское / английское название) его надо на что-то заменить. И может быть еще какие-то запрещенные символы.

Georgio 18-01-2015 21:40 2458052

Код:

@echo off

set "dir=D:\Test"

for /f "delims=" %%i in ('"2>nul dir/a-d/b/s "%dir%\default.htm""') do (
 pushd "%%~dpi"
 for /f "delims=" %%j in ('powershell "($x='*'+((gc 'default.htm')-match '<title>..*</title>')+'*'-split '<title>'-split '</title>'-replace '[*\\|:\"\"<>/?</]','_' )[1]"') do (
  ren "%%i" "%%j.htm"
  )
 popd
 )

exit/b 0


Iska 18-01-2015 22:11 2458071

Georgio, уж проще целиком на PowerShell, нежели вызывать его N раз.

deniskx, в общем — полностью программно никак. Разве что у Вас удачно окажется исключительно ANSI/1251 (или иная, но одинаковая для всех страниц кодировка, а не какая-нибудь солянка из UTF-8, отданная в KOI-8 и помеченная iso-8859-1, например. Ну, и все entities в <TITLE> также надо преобразовывать в нормальные символы.

Georgio 18-01-2015 22:27 2458078

Цитата:

<title>CMD/BAT - Переименовать файл по содержимому</title>
:wink:

Iska 18-01-2015 22:38 2458090

Georgio, ???

deniskx 18-01-2015 22:48 2458105

Georgio, некоторые файлы переименовались, некоторые нет. И кириллица запортилась. Можно PowerShell и vbs скрипты, я не против. Главное, чтобы получилось. Там еще во вложенных папках лежат txt и файлы без расширения, их бы не запортить.
Цитата:

Цитата Iska
одинаковая для всех страниц кодировка »

Все сохранено с одного сервера, так что кодировка одинаковая. Unix UTF-8 без BOM.

Georgio 18-01-2015 23:52 2458142

Цитата:

Цитата deniskx
некоторые файлы переименовались, некоторые нет. И кириллица запортилась »


Не знаю, что там у Вас такое. Данный код у меня и с UTF-8 отработал, и кириллицу не "запортил". A прикрепить образец файла, который не переименовался, и образец файла, в котором "кириллица запортилась", запаковав оба в архив, -- не вариант? Может, кто-то и разберётся...

Iska 19-01-2015 02:16 2458159

Цитата:

Цитата Georgio
Данный код у меня и с UTF-8 отработал, и кириллицу не "запортил". »

У меня на PowerShell 2.0:
Код:

Ошибка в синтаксисе команды.


Мой вариант для UTF-8:
Код:

Add-Type -AssemblyName System.Web

$sSourceFolder = "E:\Песочница\0423\01"

if(Test-Path -Path $sSourceFolder -PathType Container) {
    Get-ChildItem -Path $sSourceFolder -Include default.htm -Recurse |`
        ForEach-Object -Process {
            if(-not $_.PSIsContainer) {
                Write-Host "$($_.DirectoryName)" -ForegroundColor DarkGreen
                Write-Host "`t$($_.Name)" -ForegroundColor Green
               
                $sContent = Get-Content -Path $_.FullName -Encoding UTF8
                $oMatch  = [System.Text.RegularExpressions.Regex]::Match($sContent, "(?i)<(TITLE)[^<>]*>(?<title>[^<>]+)</\1>")
               
                if($oMatch.Success) {
                    $sNewName = ([System.Web.HttpUtility]::HtmlDecode($oMatch.Groups.Item("title").Value) -replace '[<>:"/\\|?*]+', "_") + $_.Extension
                   
                    Write-Host "`t`t$sNewName" -ForegroundColor Cyan
                   
                    Rename-Item -Path $_.FullName -NewName $sNewName
                } else {
                    Write-Host "`tCan't determine TITLE tag." -ForegroundColor Red
                }
            }
        }
} else {
    Write-Host "Can't find source folder [$sSourceFolder]." -ForegroundColor Red
}


deniskx 19-01-2015 10:36 2458243

Цитата:

Цитата Georgio
Данный код у меня и с UTF-8 отработал, и кириллицу не "запортил" »

Все дело в том, что это UTF-8 без BOM и даже Akelpad иногда путает и открывает как 1251, в результате кириллица становится вида "ПароР"
Я пересохранил в Win UTF-8 с BOM и ваш скрипт нормально отработал, кроме одного файла (но у меня очень маленькая выборка пока из 10 случайных файлов, так то их десятки тысяч). От имени остался только конец после точки. Вот с таким
Код:

<title>«The Secret Circle. The Temptation.» / «Тайный круг. Искушение.» :: Notabenoid.Com</title>
файл стал Com.htm
Наверное какие-то запрещенные символы остались. А до конвертации "Ошибка в синтаксисе команды" тоже проскакивало.
Хорошо бы сначала переконвертить все default.htm из Unix UTF-8 без BOM (Force) > Win UTF-8 с BOM. Не подскажете скрипт? Или может как-то явно указать эту кодировку в батнике.
Цитата:

Цитата Iska
Мой вариант для UTF-8 »

Простите мою невежественность, это для Powershell? А как запускать?

Iska 19-01-2015 11:01 2458255

Цитата:

Цитата deniskx
это для Powershell? »

Да.

Цитата:

Цитата deniskx
А как запускать? »

Сохранить в файл с расширением «.ps1», заменив выделенное на путь к Вашим файлам. Однократно разрешить в PowerShell исполнение неподписанных скриптов (если не делали этого ранее). Затем можно пробовать исполнять (лучше сделать копию каталога Ваших файлов и пробовать именно на копии).

deniskx 19-01-2015 17:46 2458445

Iska, спасибо все получилось. Иногда проскакивала ошибка "Слишком длинный путь или имя файла", такие файлы не переименовались, но это не страшно, их немного. Полноценный юникод, даже иероглифы и прочие зарубежные нац. символы в имена файлов перенеслись.

Iska 20-01-2015 12:48 2458770

Цитата:

Цитата deniskx
Иногда проскакивала ошибка "Слишком длинный путь или имя файла", такие файлы не переименовались, но это не страшно, их немного. »

Длинное содержимое тэга «title»? Я, к сожалению, об этом не подумал. Хотя должен был бы.

Попробуйте так:
Код:

Add-Type -AssemblyName System.Web

Set-Variable -Name MAX_PATH -Value 260 -Option Constant -ErrorAction SilentlyContinue

$sSourceFolder = "E:\Песочница\0423\01"

if(Test-Path -Path $sSourceFolder -PathType Container) {
    Get-ChildItem -Path $sSourceFolder -Include default.htm -Recurse |`
        ForEach-Object -Process {
            if(-not $_.PSIsContainer) {
                Write-Host "$($_.DirectoryName)" -ForegroundColor DarkGreen
                Write-Host "`t$($_.Name)" -ForegroundColor Green
               
                $sContent = Get-Content -Path $_.FullName -Encoding UTF8
                $oMatch  = [System.Text.RegularExpressions.Regex]::Match($sContent, "(?i)<(TITLE)[^<>]*>(?<title>[^<>]+)</\1>")
               
                if($oMatch.Success) {
                    $sNewName = ([System.Web.HttpUtility]::HtmlDecode($oMatch.Groups.Item("title").Value) -replace '[<>:"/\\|?*]+', "_") + $_.Extension
                   
                    if(((Join-Path -Path $_.DirectoryName -ChildPath $sNewName).Length) -ge $MAX_PATH) {
                        $sNewName = $sNewName.Substring((Join-Path -Path $_.DirectoryName -ChildPath $sNewName).Length - ($MAX_PATH - 1))
                    }
                   
                    Write-Host "`t`t$sNewName" -ForegroundColor Cyan
                   
                    Rename-Item -Path $_.FullName -NewName $sNewName
                } else {
                    Write-Host "`tCan't determine TITLE tag." -ForegroundColor Red
                }
            }
        }
} else {
    Write-Host "Can't find source folder [$sSourceFolder]." -ForegroundColor Red
}

Цитата:

Цитата deniskx
Полноценный юникод, даже иероглифы и прочие зарубежные нац. символы в имена файлов перенеслись. »

Это Вам свезло, что всё содержимое в одной, заранее известной кодировке.


Время: 21:11.

Время: 21:11.
© OSzone.net 2001-