Войти

Показать полную графическую версию : [решено] Удалить переносы строк


Anonymоus
22-06-2012, 04:20
Сам не смог осилить проблему встроенными средствами командного интерпретатора, прошу помощи у сообщества. Дано: директория с файлами и поддиректориями разного уровня вложенности. Нужно построить валидный xml-файл, содержащий в себе данные о каждой директории и файле (те файлы, что находятся прямо в корне, не самих поддиректориях - игнорируем), причем представляя относительные пути к ним от корня, и заменяя win-слэши (обратные) в пути, на unix-слэши, а так же получая md5-хэш файла и его размер в байтах. Практически всё это реализовал с помощью вот такого скрипта:

@Echo Off
SetLocal EnableDelayedExpansion
Set Path=%Path%;%CD%\bin

:: Имя генерируемого файла
Set OutFile=MinecraftResources.xml
:: Тут обязательно полный путь, нужно для костыля с отсечением лишнего из пути
Set DataRoot=D:\Projects\Olanet\OMSS\master\webdata\MinecraftResources


:: Пишем заголовок
:MakeHeader
>"%OutFile%" (
Echo ^<?xml version="1.0" encoding="UTF-8"?^>
Echo ^<ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/"^>
Echo ^<Name^>MinecraftResources^</Name^>
Echo ^<Prefix/^>
Echo ^<Marker/^>
Echo ^<MaxKeys^>1000^</MaxKeys^>
Echo ^<IsTruncated^>false^</IsTruncated^>
)

:: Пишем содержимое contents, файлы и директории
:: Здесь важен порядок следования, директория - её содержимое, что
:: достигается вложенным циклом
:WriteData
:: Получение вложенных поддиректорий
For /F "delims=" %%D In ('Dir "%DataRoot%\" /S /B /AD') Do (
Set Dir=%%D
:: Жуткий костыль с получением относительного пути от корня
Set Dir=!Dir:%DataRoot%\=!
Set XmlDir=!Dir:\=/!/
:: md5 - фиксированный, размер - 0
Call :GetTimestamp
Echo ^<Contents^>>>"%OutFile%"
Echo ^<Key^>!XmlDir!^</Key^>>>"%OutFile%"
Echo ^<LastModified^>!Timestamp!^</LastModified^>>>"%OutFile%"
Echo ^<ETag^>00000000000000000000000000000000^</ETag^>>>"%OutFile%"
Echo ^<Size^>0^</Size^>>>"%OutFile%"
Echo ^<StorageClass^>STANDARD^</StorageClass^>>>"%OutFile%"
Echo ^</Contents^>>>"%OutFile%"
:: Получение содержимого поддиректорий
For /F "delims=" %%F In ('Dir "%DataRoot%\!Dir!\" /B /A-D 2^>nul') Do (
Set XmlFileFullpath="%DataRoot%\!Dir!\%%~nxF"
Call :GetSize !XmlFileFullpath!
Call :GetMD5 !XmlFileFullpath!
Call :GetTimestamp
Echo ^<Contents^>>>"%OutFile%"
Echo ^<Key^>!XmlDir!%%~nxF^</Key^>>>"%OutFile%"
Echo ^<LastModified^>!Timestamp!^</LastModified^>>>"%OutFile%"
Echo ^<ETag^>!MD5!^</ETag^>>>"%OutFile%"
Echo ^<Size^>!Size!^</Size^>>>"%OutFile%"
Echo ^<StorageClass^>STANDARD^</StorageClass^>>>"%OutFile%"
Echo ^</Contents^>>>"%OutFile%"
)
)

:: Пишем конец файла
:MakeFooter
Echo ^</ListBucketResult^>>>"%OutFile%"
Exit



:: Дата-время. Рассчитано на формат даты dd.mm.yyyy, у времени
:: ведущий пробел заменяется на ведущий ноль, если есть
:GetTimestamp
For /F "tokens=1,2,3 delims=." %%A In ("%Date%") Do (Set FormattedDate=%%C-%%B-%%A)
Set FormattedTime=%Time:,=.%
Set Timestamp=%FormattedDate%T%FormattedTime: =0%0Z
Exit /B

:: Размер в байтах
:GetSize
Set Size=%~z1
Exit /B

:: Получение хэша, пришлось использовать внешнюю утилиту с очень
:: нелогичным форматом вывода
:GetMD5
For /F "tokens=1 delims=\/ " %%H In ('md5hash %1') Do (Set MD5=%%H)
Exit /B

На выходе получаю вполне валидный xml, пример начала файла:

<?xml version="1.0" encoding="UTF-8"?>
<ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<Name>MinecraftResources</Name>
<Prefix/>
<Marker/>
<MaxKeys>1000</MaxKeys>
<IsTruncated>false</IsTruncated>
<Contents>
<Key>music/</Key>
<LastModified>2012-06-22T03:07:58.870Z</LastModified>
<ETag>00000000000000000000000000000000</ETag>
<Size>0</Size>
<StorageClass>STANDARD</StorageClass>
</Contents>
<Contents>
<Key>music/calm1.ogg</Key>
<LastModified>2012-06-22T03:07:59.000Z</LastModified>
<ETag>3c5b792652b43e9876b7e7b19c0b376b</ETag>
<Size>2530812</Size>
<StorageClass>STANDARD</StorageClass>
</Contents>
<Contents>
<Key>music/calm2.ogg</Key>
<LastModified>2012-06-22T03:07:59.090Z</LastModified>
<ETag>056778e3465b292531ecd952a0cb555d</ETag>
<Size>1976731</Size>
<StorageClass>STANDARD</StorageClass>
</Contents>
<Contents>
<Key>music/calm3.ogg</Key>
<LastModified>2012-06-22T03:07:59.170Z</LastModified>
<ETag>ff32c2bfea9a23555713ca1d0739ee06</ETag>
<Size>2232651</Size>
<StorageClass>STANDARD</StorageClass>
</Contents>

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

<?xml version="1.0" encoding="UTF-8"?>
<ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/"><Name>MinecraftResources</Name><Prefix/><Marker/><MaxKeys>1000</MaxKeys><IsTruncated>false</IsTruncated><Contents><Key>music/</Key><LastModified>2012-06-22T03:07:58.870Z</LastModified><ETag>00000000000000000000000000000000</ETag><Size>0</Size><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>music/calm1.ogg</Key><LastModified>2012-06-22T03:07:59.000Z</LastModified><ETag>3c5b792652b43e9876b7e7b19c0b376b</ETag><Size>2530812</Size><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>music/calm2.ogg</Key><LastModified>2012-06-22T03:07:59.090Z</LastModified><ETag>056778e3465b292531ecd952a0cb555d</ETag><Size>1976731</Size><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>music/calm3.ogg</Key><LastModified>2012-06-22T03:07:59.170Z</LastModified><ETag>ff32c2bfea9a23555713ca1d0739ee06</ETag><Size>2232651</Size><StorageClass>STANDARD</StorageClass></Contents>


Задача, стоящая передо мной - сделать вывод скрипта идентичным вышеописанному, все данные (кроме самой первой строки) вытянуть в одну строку. Сразу генерировать однострочный xml посредством cmd мне не представляется возможным - echo вставляет перевод строки, и от этого никуда не денешься. Вытягивать все данные в одну строку, обрабатывая уже сгенерированный xml - у cmd есть ограничение на размер переменной, этот способ увы, не подходит. Я рассматривал вариант с sed, там это делается элементарно, одной командой, но хотелось бы конечно обойтись без сторонних утилит.

Iska
22-06-2012, 04:48
echo вставляет перевод строки, и от этого никуда не денешься. »
<nul set /p sVar=Text (http://forum.oszone.net/showpost.php?p=970752) пробовали?

WSH/PoSH не думали опробовать (поддержка работы с XML есть, MD5 считается)?

Anonymоus
22-06-2012, 05:27
Iska, благодарю, вы меня выручили. Всё идеально работает.
Насчет PoSH подумывал, но как-то всё время откладываю ознакомление с ним.




© OSzone.net 2001-2012