Показать полную графическую версию : [решено] переименовать файл по данным внутри него
Deminart
19-10-2018, 15:04
Добрый день! Помогите пожалуйста с написанием скрипта.
Суть такая, человек выгружает на локальный диск текстовые файлики с данными, далее они должны быть переименованы и перемещены на сетевой диск.
На данный момент процесс выглядит так:
::Рога и Копыта
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
...выгружает на локальный диск текстовые файлики с данными ...
нужно ... чтобы файлы переименовывались ... в соответствии с датой выгрузки указанной в самом файле
...Вот так выглядит нужный кусок:
ДатаНачала=19.10.2018
ДатаКонца=19.10.2018»
1. Где тут дата выгрузки
2. Какое имя должны получить файлы - оно всегда одинаково, если несколько файлов выгружаются в одном дне? Более свежий файл переписывает более старый? Приведите пример конечного имени
Хотелось бы увидеть сам файл - прикрепите его к сообщению. Интимные подробности можете забить незначащими символами
Вот так выглядит нужный кусок:
ДатаНачала=19.10.2018
ДатаКонца=19.10.2018 »
Желателен целый файл. Упакуйте его в архив и приложите к сообщению.
Deminart
22-10-2018, 08:18
1. Где тут дата выгрузки »
ДатаНачала=19.10.2018
ДатаКонца=19.10.2018
Это и есть дата "выгрузки" просто сам файл может быть например создан позже, поэтому по дате создания самого файла скрипт не годится.
2. Какое имя должны получить файлы - оно всегда одинаково, если несколько файлов выгружаются в одном дне? Более свежий файл переписывает более старый? Приведите пример конечного имени »
Файлы должны получить имя по маске #rДДММГГ, должно получится (#r221018), далее отправлены в свои соответствующие папки на сетевом диске.
Несколько файлов одним днём не выгружаются, так что файлов с одним именем быть не может.
Хотелось бы увидеть сам файл - прикрепите его к сообщению. Интимные подробности можете забить незначащими символами »
Желателен целый файл. Упакуйте его в архив и приложите к сообщению. »
Прикрепил. Изменил часть данных, структуру файла не трогал.
154661
megaloman
22-10-2018, 11:55
Deminart, @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
Сохраните код в 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
На 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
Файл есть? »
Да, файлы лежат на месте.
Перед строками с 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
P.S. Я бы сделал проще — залез внутрь обработки выгрузки из 1C и сделал бы всё зараз там. »
Возможно...Но дело в том, что бы всё это дело загрузить в 1С, файлы сначала должны попасть в нужное место с нужным именем, а выгрузка в новом клиент-банке (веб-версия) не предусматривает вообще никакой автоматизации.
Или Вы имели в виду что бы 1С-ка сразу всё забирала с локального диска?...Кроме 1С есть ещё одна программы для загрузки этих файлов, в общем не вариант...
Deminart
23-10-2018, 10:07
В общем пока отвечал, уже помогли на другом известном форуме. В целом решение рабочее и для моих нужд подходит.
@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
Deminart, @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
У Вас нет файлов по указанной маске. Возможно, Ваши исходные txt-файлы имеют другую маску. Попробуйте »
Да, спасибо за объяснение, всё отлично работает. Ваш вариант оказался наиболее правильным.
Большое спасибо за помощь!
megaloman, Iska
а выгрузка в новом клиент-банке (веб-версия) не предусматривает вообще никакой автоматизации. »
Это печально.
© OSzone.net 2001-2012
vBulletin v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.