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

Deminart 19-10-2018 15:04 2836590

переименовать файл по данным внутри него
 
Добрый день! Помогите пожалуйста с написанием скрипта.

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

На данный момент процесс выглядит так:

Код:

::Рога и Копыта
for /F "delims=. tokens=1-3" %%a in ('echo %date:.=%') do rename *.txt "#r%%c%%b%%a.txt"
move /y "C:\файл\Рога и Копыта\*.txt" "\\192.168.1.1\Рога и Копыта\файл"
::Рога и Копыта 2
for /F "delims=. tokens=1-3" %%a in ('echo %date:.=%') do rename *.txt "#r%%c%%b%%a.txt"
move /y "C:\файл\Рога и Копыта2\*.txt" "\\192.168.1.1\Рога и Копыта2\файл"
::Рога и Копыта 3
for /F "delims=. tokens=1-3" %%a in ('echo %date:.=%') do rename *.txt "#r%%c%%b%%a.txt"
move /y "C:\файл\Рога и Копыта3\*.txt" "\\192.168.1.1\Рога и Копыта3\файл"

и тд

Данный bat стоит в планировщике задач и выполняется с интервалом в 10 мин.

Знаю, что возможно тут всё криво, но эта простая схема работала, до текущего момента.

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

Вот так выглядит нужный кусок:

ДатаНачала=19.10.2018
ДатаКонца=19.10.2018

megaloman 19-10-2018 18:37 2836606

Цитата:

Цитата Deminart
...выгружает на локальный диск текстовые файлики с данными ...
нужно ... чтобы файлы переименовывались ... в соответствии с датой выгрузки указанной в самом файле

...Вот так выглядит нужный кусок:
ДатаНачала=19.10.2018
ДатаКонца=19.10.2018»

1. Где тут дата выгрузки
2. Какое имя должны получить файлы - оно всегда одинаково, если несколько файлов выгружаются в одном дне? Более свежий файл переписывает более старый? Приведите пример конечного имени

Хотелось бы увидеть сам файл - прикрепите его к сообщению. Интимные подробности можете забить незначащими символами

Iska 19-10-2018 19:13 2836610

Цитата:

Цитата Deminart
Вот так выглядит нужный кусок:
ДатаНачала=19.10.2018
ДатаКонца=19.10.2018 »

Желателен целый файл. Упакуйте его в архив и приложите к сообщению.

Deminart 22-10-2018 08:18 2836935

Вложений: 1
Цитата:

Цитата megaloman
1. Где тут дата выгрузки »

ДатаНачала=19.10.2018
ДатаКонца=19.10.2018

Это и есть дата "выгрузки" просто сам файл может быть например создан позже, поэтому по дате создания самого файла скрипт не годится.

Цитата:

Цитата megaloman
2. Какое имя должны получить файлы - оно всегда одинаково, если несколько файлов выгружаются в одном дне? Более свежий файл переписывает более старый? Приведите пример конечного имени »

Файлы должны получить имя по маске #rДДММГГ, должно получится (#r221018), далее отправлены в свои соответствующие папки на сетевом диске.
Несколько файлов одним днём не выгружаются, так что файлов с одним именем быть не может.

Цитата:

Цитата megaloman
Хотелось бы увидеть сам файл - прикрепите его к сообщению. Интимные подробности можете забить незначащими символами »

Цитата:

Цитата Iska
Желателен целый файл. Упакуйте его в архив и приложите к сообщению. »

Прикрепил. Изменил часть данных, структуру файла не трогал.

Файл 154661

megaloman 22-10-2018 11:55 2836961

Deminart,
Сохраните код в 1251 ("Windows") кодировке
Код:

@Echo off
        Chcp 1251 >nul

        Set "FindData=ДатаКонца"
        Set "Pref=#r"

        Call :ReMove "C:\Файл\Рога и копыта 1\#r??????.txt" "\\192.168.1.1\Test1\Рога и копыта 1\Файл"
        Call :ReMove "C:\Файл\Рога и копыта 2\#r??????.txt" "\\192.168.1.1\Test1\Рога и копыта 2\Файл"
        Call :ReMove "C:\Файл\Рога и копыта 3\#r??????.txt" "\\192.168.1.1\Test1\Рога и копыта 3\Файл"
GoTo :Eof

:ReMove
        FOR %%f IN ("%~1") DO Call :DFind "%%f" "%FindData%" "%~2" "%Pref%"
GoTo :Eof

:DFind
        Set /A n=0
        FOR /F "usebackq skip=2 tokens=2,3,4 delims==." %%i IN (`Find /I "%~2=" %1`) DO (Set "S1=%%i%%j" &Set "S2=%%k" &Set /A n+=1)
        If %n%==0 Exit /B 1
       
        Copy "%~1" "%~1.bak" >nul
        Move /Y "%~1" "%~3\%~4%S1%%S2:~-2%%~x1" >nul
Exit /B %ErrorLevel%

На всякий случай файл с оригинальным названием копирую в bak-файл. Если не надо - убейте строку.
И еще, дату я беру в строке с "ДатаКонца". В примере таких строк у Вас две.

Deminart 22-10-2018 14:00 2836977

Цитата:

Цитата megaloman
Сохраните код в 1251 ("Windows") кодировке »

Разбираюсь с Вашим скриптом, пока безрезультатно...

Скрипт выполняется, без ошибок, но в то же время как будто ничего не делает.


Скрытый текст
C:\test>Chcp 1251 1>nul

C:\test>Set "FindData=ДатаКонца"

C:\test>Set "Pref=#r"

C:\test>Call :ReMove "C:\test\1\#r??????.txt" "\\192.168.1.88\share\1\"

C:\test>FOR %f IN ("C:\test\1\#r??????.txt") DO Call :DFind "%f" "ДатаКонца" "\\192.168.1.88\share\1\" "#r"

C:\test>GoTo :Eof

C:\test>Call :ReMove "C:\test\2\#r??????.txt" "\\192.168.1.88\share\2\"

C:\test>FOR %f IN ("C:\test\2\#r??????.txt") DO Call :DFind "%f" "ДатаКонца" "\\192.168.1.88\share\2\" "#r"

C:\test>GoTo :Eof

C:\test>Call :ReMove "C:\test\3\#r??????.txt" "\\192.168.1.88\share\3\"

C:\test>FOR %f IN ("C:\test\3\#r??????.txt") DO Call :DFind "%f" "ДатаКонца" "\\192.168.1.88\share\3\" "#r"

C:\test>GoTo :Eof

C:\test>Call :ReMove "C:\test\#r??????.txt" "\\192.168.1.88\share\4"

C:\test>FOR %f IN ("C:\test\#r??????.txt") DO Call :DFind "%f" "ДатаКонца" "\\192.168.1.88\share\4" "#r"

C:\test>GoTo :Eof

C:\test>GoTo :Eof

Iska 23-10-2018 00:35 2837116

На WSH:
Скрытый текст
Код:

Option Explicit

Dim strSourceFolder
Dim strDestFolder

Dim objFSO
Dim objFile

Dim objRegExp

Dim strContent
Dim strNewFileName


If WScript.Arguments.Count = 2 Then
        strSourceFolder = WScript.Arguments.Item(0)
        strDestFolder  = WScript.Arguments.Item(1)
       
        Set objFSO = WScript.CreateObject("Scripting.FileSystemObject")
       
        If objFSO.FolderExists(strSourceFolder) Then
                If objFSO.FolderExists(strDestFolder) Then
                        Set objRegExp = WScript.CreateObject("VBScript.RegExp")
                       
                        With objRegExp
                                .Pattern    = "^#r\d+\.txt$"
                                .IgnoreCase = True
                        End With
                       
                        For Each objFile In objFSO.GetFolder(strSourceFolder).Files
                                If objRegExp.Test(objFile.Name) Then
                                        With objFSO.OpenTextFile(objFile.Path)
                                                strContent = .ReadAll()
                                                .Close
                                        End With
                                       
                                        With WScript.CreateObject("VBScript.RegExp")
                                                .Pattern    = "^ДатаНачала=(\d{2})\.(\d{2})\.(\d{4})$"
                                                .IgnoreCase = True
                                                .MultiLine  = True
                                               
                                                If .Test(strContent) Then
                                                        With .Execute(strContent).Item(0).Submatches
                                                                strNewFileName = "#r" & .Item(2) & .Item(1) & .Item(0) & ".txt"
                                                        End With
                                                       
                                                        objFile.Move objFSO.BuildPath(strDestFolder, strNewFileName)
                                                Else
                                                        WScript.Echo "Can't find pattern [" & .Pattern & "] in content of file [" & objFile.Name & "]."
                                                End If
                                        End With
                                Else
                                        ' Nothing to do
                                End If
                        Next
                       
                        Set objRegExp = Nothing
                Else
                        WScript.Echo "Can't find destination folder [" & strDestFolder & "]."
                        WScript.Quit 3
                End If
        Else
                WScript.Echo "Can't find source folder [" & strSourceFolder & "]."
                WScript.Quit 2
        End If
       
        Set objFSO = Nothing
Else
        WScript.Echo "Usage: cscript.exe //nologo """ & WScript.ScriptName & """ <Source folder> <Destination folder>"
        WScript.Quit 1
End If

WScript.Quit 0


Примерный пакетный файл для обработки на основе Вашего пакетного файла:
Скрытый текст
Код:

@echo off
setlocal enableextensions enabledelayedexpansion

rem Рога и Копыта
cscript.exe //nologo "C:\Мои проекты\0213\Sample.vbs" "C:\файл\Рога и Копыта" "\\192.168.1.1\Рога и Копыта"

rem Рога и Копыта 2
cscript.exe //nologo "C:\Мои проекты\0213\Sample.vbs" "C:\файл\Рога и Копыта2" "\\192.168.1.1\Рога и Копыта2"

rem Рога и Копыта 3
cscript.exe //nologo "C:\Мои проекты\0213\Sample.vbs" "C:\файл\Рога и Копыта3" "\\192.168.1.1\Рога и Копыта3"

endlocal
exit /b 0


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

P.S. Я бы сделал проще — залез внутрь обработки выгрузки из 1C и сделал бы всё зараз там.

Deminart 23-10-2018 10:00 2837149

Вложений: 1
  • test.txt (0 bytes, скачиваний: 0)
Цитата:

Цитата megaloman
Файл есть? »

Да, файлы лежат на месте.

Цитата:

Перед строками с Call вставьте
Цитата:

dir "C:\test\1\#r??????.txt"
Получается вот что:

Скрытый текст
C:\test>C:\test\test1.bat
Том в устройстве C не имеет метки.
Серийный номер тома: 9AD6-96C6

Содержимое папки C:\test\1

Файл не найден

Содержимое папки C:\test


Содержимое папки C:\test

Файл не найден

Содержимое папки C:\test\1

Файл не найден

Том в устройстве \\192.168.1.68\share имеет метку local
Серийный номер тома: 62C8-A2BB

Содержимое папки \\192.168.1.68\share\1

22.10.2018 14:21 <DIR> .
22.10.2018 14:21 <DIR> ..
0 файлов 0 байт
2 папок 28*139*134*976 байт свободно
Том в устройстве C не имеет метки.
Серийный номер тома: 9AD6-96C6

Содержимое папки C:\test\1

Файл не найден

Содержимое папки C:\test


Содержимое папки C:\test

Файл не найден

Содержимое папки C:\test\2

Файл не найден

Том в устройстве \\192.168.1.68\share имеет метку local
Серийный номер тома: 62C8-A2BB

Содержимое папки \\192.168.1.68\share\2

22.10.2018 14:17 <DIR> .
22.10.2018 14:17 <DIR> ..
0 файлов 0 байт
2 папок 28*139*134*976 байт свободно
Том в устройстве C не имеет метки.
Серийный номер тома: 9AD6-96C6

Содержимое папки C:\test\1

Файл не найден

Содержимое папки C:\test


Содержимое папки C:\test

Файл не найден

Содержимое папки C:\test\3

Файл не найден

Том в устройстве \\192.168.1.68\share имеет метку local
Серийный номер тома: 62C8-A2BB

Содержимое папки \\192.168.1.68\share\3

22.10.2018 14:17 <DIR> .
22.10.2018 14:17 <DIR> ..
0 файлов 0 байт
2 папок 28*139*134*976 байт свободно
Том в устройстве C не имеет метки.
Серийный номер тома: 9AD6-96C6

Содержимое папки C:\test\1

Файл не найден

Содержимое папки C:\test


Содержимое папки C:\test


Содержимое папки C:\test

19.10.2018 14:40 6*966 #r270918.txt
1 файлов 6*966 байт
0 папок 19*197*730*816 байт свободно

Том в устройстве \\192.168.1.68\share имеет метку local
Серийный номер тома: 62C8-A2BB

Содержимое папки \\192.168.1.68\share\4

22.10.2018 14:52 <DIR> .
22.10.2018 14:52 <DIR> ..
0 файлов 0 байт
2 папок 28*139*134*976 байт свободно

C:\test>dir "C:\test\1\#r??????.txt"


Файлик прикрепил:
Файл 154676


Цитата:

Цитата Iska
P.S. Я бы сделал проще — залез внутрь обработки выгрузки из 1C и сделал бы всё зараз там. »

Возможно...Но дело в том, что бы всё это дело загрузить в 1С, файлы сначала должны попасть в нужное место с нужным именем, а выгрузка в новом клиент-банке (веб-версия) не предусматривает вообще никакой автоматизации.
Или Вы имели в виду что бы 1С-ка сразу всё забирала с локального диска?...Кроме 1С есть ещё одна программы для загрузки этих файлов, в общем не вариант...

Deminart 23-10-2018 10:07 2837151

В общем пока отвечал, уже помогли на другом известном форуме. В целом решение рабочее и для моих нужд подходит.

Код:

@echo off
SetLocal EnableExtensions
for %%n in (*.txt) do for /f "UseBackQ tokens=1,2 delims==" %%a in ("%%n") do if "%%a"=="ДатаНачала" set "d=%%b"
for /F "delims=. tokens=1-3" %%a in ("%d%") do call :renX *.txt %%a %%b %%c
goto :eof

:renX [orig] [dd] [mm] [yyyy]
set dd=%~2
set mm=%~3
set yy=%~4
set yy=%yy:~2%
ren "%~1" "#r%dd%%mm%%yy%.txt"
exit /b

Единственное после
@echo off
думаю добавить
cd C:\test\1
далее сам скрипт
после
ren "%~1" "#r%dd%%mm%%yy%.txt"
добавить непосредственно перенос
move /y "C:\test\1\*.txt" "\\192.168.1.68\share\1"

ну и так далее для всех папок с файлами...
...
cd C:\test\2
...
move /y "C:\test\2\*.txt" "\\192.168.1.68\share\2"
...

megaloman 23-10-2018 10:46 2837160

Deminart,
У Вас нет файлов по указанной маске. Возможно, Ваши исходные txt-файлы имеют другую маску. Попробуйте
Код:

@Echo off
        Chcp 1251 >nul

        Set "FindData=ДатаКонца"
        Set "Pref=#r"

        Call :ReMove "C:\Файл\Рога и копыта 1\*.txt" "\\192.168.1.1\Test1\Рога и копыта 1\Файл"
        Call :ReMove "C:\Файл\Рога и копыта 2\*.txt" "\\192.168.1.1\Test1\Рога и копыта 2\Файл"
        Call :ReMove "C:\Файл\Рога и копыта 3\*.txt" "\\192.168.1.1\Test1\Рога и копыта 3\Файл"
GoTo :Eof

:ReMove
        FOR %%f IN ("%~1") DO Call :DFind "%%f" "%FindData%" "%~2" "%Pref%"
GoTo :Eof

:DFind
        Set /A n=0
        FOR /F "usebackq skip=2 tokens=2,3,4 delims==." %%i IN (`Find /I "%~2=" %1`) DO (Set "S1=%%i%%j" &Set "S2=%%k" &Set /A n+=1)
        If %n%==0 Exit /B 1
       
        Copy "%~1" "%~1.bak" >nul
        Move /Y "%~1" "%~3\%~4%S1%%S2:~-2%%~x1" >nul
Exit /B %ErrorLevel%

Путь к выходной папке указывайте без \ на конце

Deminart 23-10-2018 11:00 2837161

Цитата:

Цитата megaloman
У Вас нет файлов по указанной маске. Возможно, Ваши исходные txt-файлы имеют другую маску. Попробуйте »

Да, спасибо за объяснение, всё отлично работает. Ваш вариант оказался наиболее правильным.

Большое спасибо за помощь!
megaloman, Iska

Iska 23-10-2018 21:01 2837264

Цитата:

Цитата Deminart
а выгрузка в новом клиент-банке (веб-версия) не предусматривает вообще никакой автоматизации. »

Это печально.


Время: 23:12.

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