PDA

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


Hixi
30-05-2013, 18:23
Помогите решить задачу на VBS.
Нужно найти определенный текст в текстовых файлах находящихся в одной директории.
При совпадении с определенным текстом переносить в указанный путь.

Если в файле найден текст "QWERTY" , то перенести этот файл в C:\QWERTY\"текущая дата"
Если в файле найден текст "ASDFGР" , то перенести этот файл в C:\ASDFGР\"текущая дата"
и т.д.

Необходимая задача уже решалась когда-то на CMD/BAT http://forum.oszone.net/nextnewesttothread-242495.html

Iska
30-05-2013, 18:52
и т.д. »
Какова кодировка текстовых файлов (если в и т.д. попадёт кириллица)?

Необходимая задача уже решалась когда-то на CMD/BAT http://forum.oszone.net/nextnewesttothread-242495.html »
Почему не устраивает то решение?

Hixi
30-05-2013, 19:00
Прошу прощения, кириллица присутствует. Кодировка Dos-866
Нет возможности истользовать BAT. Необходимо решение на VBS.

Iska
30-05-2013, 19:07
Прошу прощения, кириллица присутствует. »
Какова кодировка текстовых файлов (если в и т.д. попадёт кириллица)? »
?

Если в файле найден текст "QWERTY" , то перенести этот файл в C:\QWERTY\"текущая дата"
Если в файле найден текст "ASDFGР" , то перенести этот файл в C:\ASDFGР\"текущая дата"
и т.д. »
Перечень «QWERTY», «ASDFGР» и «и т.д.» определён? Где будет находиться/задаваться — в самом скрипте, в параметрах скрипта, во внешнем текстовом файле (при большом количестве)?

Hixi
30-05-2013, 19:13
Какова кодировка текстовых файлов (если в и т.д. попадёт кириллица)? »
? »
DOS-866

Перечень «QWERTY», «ASDFGР» и «и т.д.» определён? Где будет находиться/задаваться — в самом скрипте, в параметрах скрипта, во внешнем текстовом файле (при большом количестве)? »
Перечень не определен, может дополняться/изменяться. Указывать лучше в параметрах скрипта (зачений не более 20)

Iska
31-05-2013, 06:53
Hixi, пробуйте:
Option Explicit

Dim strSourceFolder
Dim strDestFolder

Dim objFile

Dim strText
Dim strPhrase

Dim strDate
Dim strDestPath


If WScript.Arguments.Count >= 1 Then
strSourceFolder = WScript.CreateObject("WScript.Shell").CurrentDirectory
strDestFolder = "c:\"

With WScript.CreateObject("Scripting.FileSystemObject")
If .FolderExists(strDestFolder) Then
WScript.Echo "Source folder: [" & strSourceFolder & "]"
WScript.Echo "Destination folder: [" & strDestFolder & "]"
WScript.Echo "--------------------------------------------"

strDate = GetLocalDate()

For Each objFile In .GetFolder(strSourceFolder).Files
If LCase(.GetExtensionName(objFile.Name)) = "txt" Then
WScript.Echo "File: " & objFile.Path

With objFile.OpenAsTextStream()
strText = StrConvert(.ReadAll(), "windows-1251", "cp866")
.Close
End With

For Each strPhrase In WScript.Arguments
If InStr(1, strText, strPhrase, vbTextCompare) > 0 Then
WScript.Echo Space(4) & "Phrase found: " & strPhrase

strDestPath = .BuildPath(.BuildPath(strDestFolder, strPhrase), strDate)

CreateFolderEx strDestPath
objFile.Move .BuildPath(strDestPath, "\")

WScript.Echo Space(4) & "Moved to folder [" & strDestPath & "]"
End If
Next
End If
Next
Else
WScript.Echo "Can't find destination folder [" & strDestFolder & "]"
End If
End With
Else
WScript.Echo "Usage: cscript.exe //nologo """ & WScript.ScriptName & """ <Phrase 1> <Phrase 2> ... <Phrase N>"
End If

WScript.Quit 0
'=============================================================================

'=============================================================================
Function GetLocalDate()
Dim objSWbemObjectEx

With GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
For Each objSWbemObjectEx In .ExecQuery("SELECT LocalDateTime FROM Win32_OperatingSystem")
GetLocalDate = Left(objSWbemObjectEx.LocalDateTime, 8)
Exit For
Next
End With
End Function
'=============================================================================

'=============================================================================
Sub CreateFolderEx(strPath)
With WScript.CreateObject("Scripting.FileSystemObject")
If Not .FolderExists(strPath) Then
CreateFolderEx .GetParentFolderName(strPath)
.CreateFolder strPath
End If
End With
End Sub
'=============================================================================

'=============================================================================
' HKEY_CLASSES_ROOT\MIME\Database\Charset
' cp866, windows-1251, koi8-r, unicode, utf-8, _autodetect
'=============================================================================
Function StrConvert(ByVal strText, ByVal strSourceCharset, ByVal strDestCharset)
Const adTypeText = 2
Const adModeReadWrite = 3


With WScript.CreateObject("ADODB.Stream")
.Type = adTypeText
.Mode = adModeReadWrite

.Open

.Charset = strSourceCharset
.WriteText strText

.Position = 0
.Charset = strDestCharset
StrConvert = .ReadText

.Close
End With
End Function
'=============================================================================

Пример вызова скрипта:
cscript.exe //nologo "Script.vbs" "рабы не" Мама
Возможный результат:
Source folder: [E:\Песочница\0266]
Destination folder: [c:\]
--------------------------------------------
File: E:\Песочница\0266\0001.txt
Phrase found: Мама
Moved to folder [c:\Мама\20130531]
File: E:\Песочница\0266\0002.txt
Phrase found: рабы не
Moved to folder [c:\рабы не\20130531]
File: E:\Песочница\0266\0003.txt

Hixi
31-05-2013, 10:36
Спасибо! а если требуется вывод данных из файла (текста для поиска и при совпадении перемещение в указанную заранее дирректорию, нужна привязка текст\путь (текст для поиска "привет" при совпадении переместить в C:\dsa\123, файлы с текстом "Пока" при совпадении переместить в D:\фыва\908 ))?

Iska
31-05-2013, 11:04
Hixi, пожалуйста, ещё раз и по-русски: не могу выудить смысл из Вашего поста.

Hixi
31-05-2013, 11:40
Предположим есть список искомого текста и при нахождение одного из слов в файлах переместить в привязанную к слову дирректорию.

Родина = C:\try\"год"\"месяц"\"год_месяц_день"\прием
Горы = E:\asd\"год"\"месяц"\"год_месяц_вчерашний день"\прием
Привет = D:\789
Тополь-М = F:\14\тру

Iska
31-05-2013, 20:29
"год", "месяц", "год_месяц_день" — это, я так понял, шаблоны? В которые при обработке должны подставляться значения текущей даты?

Hixi
01-06-2013, 02:35
"год", "месяц", "год_месяц_день" — это, я так понял, шаблоны? В которые при обработке должны подставляться значения текущей даты? »
В идеале да.

Iska
01-06-2013, 08:06
Аппетит растёт во время еды? Это, в принципе, возможно. При большом желании можно даже внедрить поддержку функций вида «вчерашний день» и т.п.

Однако, поскольку в WSH крайне ограниченная реализация форматирования даты/времени:
vbGeneralDate 0 Display a date and/or time. If there is a date part, display it as a short date. If there is a time part, display it as a long time. If present, both parts are displayed.

vbLongDate 1 Display a date using the long date format specified in your computer's regional settings.

vbShortDate 2 Display a date using the short date format specified in your computer's regional settings.

vbLongTime 3 Display a time using the time format specified in your computer's regional settings.

vbShortTime 4 Display a time using the 24-hour format (hh:mm).

— большого желания делать свою реализацию я не испытываю.


1. Какие шаблоны Вы хотите использовать — перечислите?
2. Какова будет кодировка текстового файла с парами «"Фраза для поиска"="Путь для перемещения"»?

Hixi
02-06-2013, 00:00
1. Шаблон нужен исключительно краткий. (C:\qwer\Привет\2013\05\2013_05_31). В некоторых случаях перенос файла, при совпадении с найденым текстом, должен осуществляться в предшествующую дату. В остальных необходимости нет.
2. Кодировка пойдет любая (на ваше усмотрение). Для удобства ввода пойдет windows-1251 или cp866.

Iska
03-06-2013, 02:06
1. Шаблон нужен исключительно краткий. »
Это три формата/функции: год, месяц, дата в нестандартном формате.

В общем, держите:
Option Explicit

Dim strIniFile

Dim objDictionary
Dim objRegExp
Dim objRegExp4Eval
Dim objMatchCollection

Dim strLine
Dim strParameter
Dim strValue

Dim strSourceFolder

Dim objFile

Dim strText
Dim strPhrase

Dim strDate
Dim strDestPath


If WScript.Arguments.Count = 1 Then
With WScript.CreateObject("Scripting.FileSystemObject")
strIniFile = WScript.Arguments.Item(0)

If .FileExists(strIniFile) Then
Set objDictionary = WScript.CreateObject("Scripting.Dictionary")
Set objRegExp = WScript.CreateObject("VBScript.RegExp")
Set objRegExp4Eval = WScript.CreateObject("VBScript.RegExp")

objRegExp.Pattern = "^\s*("")?([^\1=]+?)\1\s*=\s*("")?(.+?)\3\s*$"
objRegExp4Eval.Pattern = "(\?)([^\?]+?)\1"

strSourceFolder = WScript.CreateObject("WScript.Shell").CurrentDirectory

WScript.Echo "Ini file: [" & strIniFile & "]"
WScript.Echo "--------------------------------------------"

With .OpenTextFile(strIniFile)
Do Until .AtEndOfStream
strLine = .ReadLine()

If objRegExp.Test(strLine) Then
Set objMatchCollection = objRegExp.Execute(strLine)

strParameter = objMatchCollection.Item(0).SubMatches(1)
strValue = objMatchCollection.Item(0).SubMatches(3)

Do While objRegExp4Eval.Test(strValue)
strValue = objRegExp4Eval.Replace(strValue, Eval(objRegExp4Eval.Execute(strValue).Item(0).Submatches.Item(1)))
Loop

WScript.Echo "Parameter: [" & strParameter & "]"
WScript.Echo "Value: [" & strValue & "]"
WScript.Echo
Else
WScript.Echo "Can't determine line [" & strLine & "]"
End If

If Not objDictionary.Exists(strParameter) Then
objDictionary.Add strParameter, strValue
Else
WScript.Echo "Duplicate parameter [" & strParameter & "] found"
End If
Loop

.Close
End With

WScript.Echo
WScript.Echo "Source folder: [" & strSourceFolder & "]"
WScript.Echo "--------------------------------------------"

For Each objFile In .GetFolder(strSourceFolder).Files
If LCase(.GetExtensionName(objFile.Name)) = "txt" Then
WScript.Echo "File: " & objFile.Path

With objFile.OpenAsTextStream()
strText = StrConvert(.ReadAll(), "windows-1251", "cp866")
.Close
End With

For Each strPhrase In objDictionary.Keys
If InStr(1, strText, strPhrase, vbTextCompare) > 0 Then
WScript.Echo Space(4) & "Phrase found: " & strPhrase

strDestPath = objDictionary.Item(strPhrase)

CreateFolderEx strDestPath
objFile.Move .BuildPath(strDestPath, "\")

WScript.Echo Space(4) & "Moved to folder [" & strDestPath & "]"
End If
Next
End If
Next

objDictionary.RemoveAll

Set objRegExp = Nothing
Set objDictionary = Nothing
Else
WScript.Echo "Can't find ini file [" & strIniFile & "]"
End If
End With
Else
WScript.Echo "Usage: cscript.exe //nologo """ & WScript.ScriptName & """ <ini file>"
End If

WScript.Quit 0
'=============================================================================

'=============================================================================
Sub CreateFolderEx(strPath)
With WScript.CreateObject("Scripting.FileSystemObject")
If Not .FolderExists(strPath) Then
CreateFolderEx .GetParentFolderName(strPath)
.CreateFolder strPath
End If
End With
End Sub
'=============================================================================

'=============================================================================
' HKEY_CLASSES_ROOT\MIME\Database\Charset
' cp866, windows-1251, koi8-r, unicode, utf-8, _autodetect
'=============================================================================
Function StrConvert(ByVal strText, ByVal strSourceCharset, ByVal strDestCharset)
Const adTypeText = 2
Const adModeReadWrite = 3


With WScript.CreateObject("ADODB.Stream")
.Type = adTypeText
.Mode = adModeReadWrite

.Open

.Charset = strSourceCharset
.WriteText strText

.Position = 0
.Charset = strDestCharset
StrConvert = .ReadText

.Close
End With
End Function
'=============================================================================
и играйтесь.

Вызов:
cscript.exe //nologo "Script.vbs" "Путь\ini-файл"

Внутри ini-файла можно указывать выражения на VBScript, обрамляя их символами «?» — лепите, что пожелаете. Пробельные символы обрезаются, если потребны — обрамляйте кавычками. Кодировка ini-файла — «windows-1251».

Пример ini-файла, на основе приведённых Вами данных (http://forum.oszone.net/post-2159792.html#post2159792):
Родина = C:\try\?CStr(Year(Now()))?\?Right("00" & CStr(Month(Now())), 2)?\?CStr(Year(Now())) & "_" & Right("00" & CStr(Month(Now())), 2) & "_" & Right("00" & CStr(Day(Now())), 2)?\прием
Горы = E:\asd\?CStr(Year(DateAdd("d", -1, Now())))?\?Right("00" & CStr(Month(DateAdd("d", -1, Now()))), 2)?\?CStr(Year(DateAdd("d", -1, Now()))) & "_" & Right("00" & CStr(Month(DateAdd("d", -1, Now()))), 2) & "_" & Right("00" & CStr(Day(DateAdd("d", -1, Now()))), 2)?\прием
Привет = D:\789
Тополь-М = F:\14\тру


Возможный результат:
Ini file: [0001.ini]
--------------------------------------------
Parameter: [Родина]
Value: [C:\try\2013\06\2013_06_03\прием]

Parameter: [Горы]
Value: [E:\asd\2013\06\2013_06_02\прием]

Parameter: [Привет]
Value: [D:\789]

Parameter: [Тополь-М]
Value: [F:\14\тру]


Source folder: [E:\Песочница\0267]
--------------------------------------------
File: E:\Песочница\0267\0001.txt
File: E:\Песочница\0267\0002.txt
File: E:\Песочница\0267\0003.txt
File: E:\Песочница\0267\0004.txt
Phrase found: Горы
Moved to folder [E:\asd\2013\06\2013_06_02\прием]
File: E:\Песочница\0267\0005.txt
Phrase found: Родина
Moved to folder [C:\try\2013\06\2013_06_03\прием]

***** script completed - exit code: 0 *****

Hixi
04-06-2013, 22:05
Спасибо! Все работает как надо!)




© OSzone.net 2001-2012