Используйте vbscript для изменения текстового файла - PullRequest
7 голосов
/ 23 июня 2010

Каждый день мы получаем плоский текстовый файл. В некоторые дни в файле есть строки, которые необходимо удалить, прежде чем он сможет быть обработан. Эти строки могут появляться в разных местах, но всегда начинаются с символов 6999 или 7999. Мы хотели бы запустить скрипт, который удалит эти конкретные строки. Однако, и это далеко от меня, в любом месте, где есть строка, начинающаяся с 6999, будет непосредственно перед ней строка, начинающая 5442, которую также необходимо удалить, но только если она появляется непосредственно перед строкой 6999.

Мы магазин Windows и запустили бы этот скрипт как часть простого пакетного файла в Windows. Мы не используем ни Unix, ни Linux, ни желание.

Расширение имени файла отражает дату. Сегодняшний файл будет file.100621, завтра будет file.100622. У меня возникли проблемы с этим аспектом, так как кажется, что VBScript не любит файл. *

Вот пример текстового файла:

4006006602    03334060000100580                                                 
40060066039    0334070000100580                                                 
700600000011571006210060001255863                                               
544264287250111000025000000000040008000801                                      
6999001000000000000000000000000000000000000000000000000000                      
6999001000000000000000000000000000000000000000000000000000                      
6999001000000000000000000000000000000000000000000000000000                      
799900000011571006210030000000000                                               
8007000000115710062102530054008920  

Мы хотели бы удалить 5 строк в этом файле (строка 5442, три строки 6999 и строка 7999).

Вот пример скрипта, который я нашел на этом сайте, изменил и добился определенного успеха, но не знаю, как удалять строки (знаю только, как заменить данные в строке). Я понимаю, что это либо потребует серьезных модификаций, либо будет полностью исключено, но я публикую это, чтобы дать представление о том, что, по моему мнению, мы ищем. Я помещаю это в каталог с cscript.exe и вызываю его из простого командного файла:

Set objFS = CreateObject("Scripting.FileSystemObject")
strFile = "c:\temp\file.100621"
Set objFile = objFS.OpenTextFile(strFile)
Do Until objFile.AtEndOfStream
    strLine = objFile.ReadLine
    If InStr(strLine,"6999")> 0 Then
        strLine = Replace(strLine,"6999","delete line")
    End If 
    WScript.Echo strLine
Loop

Что дает мне это:

40060066039    0334070000100580                                                 
700600000011571006210060001255863                                               
544264287250111000025000000000040008000801                                      
delete line001000000000000000000000000000000000000000000000000000                      
delete line001000000000000000000000000000000000000000000000000000                      
delete line001000000000000000000000000000000000000000000000000000                      
799900000011571006210030000000000                                               
8007000000115710062102530054008920  

Закрыть! просто нужно удалить строки вместо записи "удалить строку". Вот мои конкретные потребности, основанные на том, что я знаю:

  1. Получить скрипт для обработки любого файла в каталоге (и будет только 1 за раз, но расширение меняется каждый день)
  2. Получить скрипт для удаления любой строки, которая начинается с 5442, непосредственно перед строкой, которая начинается 6999
  3. Получить скрипт для полного удаления тех строк, которые начинаются с 6999 и 7999

Ответы [ 4 ]

7 голосов
/ 23 июня 2010

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

Select Case Wscript.Arguments.Count
    case 1:
        strInput = GetFile(WScript.Arguments(0))
        RemoveUnwantedLines strInput, strInput
        RemoveBlankLines strInput
    case 2:
        strInput = GetFile(WScript.Arguments(0))
        strOutput = Wscript.Arguments(1)
        RemoveUnwantedLines strInput, strOutput
        RemoveBlankLines strOutput
End Select

Function GetFile(strDirectory)
    Set objFSO = CreateObject("Scripting.FileSystemObject")
    Set objFolder = objFSO.GetFolder(strDirectory)
    dateLastModified = Null
    strFile = ""
    For Each objFile in objFolder.Files
        If IsNull(dateLastModified) Then
            dateLastModified = objFile.DateLastModified
            strFile = objFile.Path
        ElseIf dateLastModified < objFile.DateLastModified Then
            dateLastModified = objFile.DateLastModified
            strFile = objFile.Path
        End If
    Next
    GetFile = strFile
End Function

Sub RemoveUnwantedLines(strInputFile, strOutputFile)
        'Open the file for reading.
    Set objFile = CreateObject("Scripting.FileSystemObject").OpenTextFile(strInputFile,1)
        'Read the entire file into memory.
    strFileText = objFile.ReadAll
        'Close the file.
    objFile.Close
        'Split the file at the new line character. *Use the Line Feed character (Char(10))
    arrFileText = Split(strFileText,Chr(10))
        'Open the file for writing.
    Set objFile = CreateObject("Scripting.FileSystemObject").OpenTextFile(strOutputFile,2,true)
        'Loop through the array of lines looking for lines to keep.
    For i = LBound(arrFileText) to UBound(arrFileText)
            'If the line is not blank process it.
        If arrFileText(i) <> "" Then
                'If the line starts "5442", see if the next line is "6999".
            If Left(arrFileText(i),4) = "5442" Then
                    'Make sure the next line exists (Don't want an out of bounds exception).
                If i + 1 <= UBound(arrFileText)Then
                        'If the next line is not "6999" 
                    If Left(arrFileText(i + 1), 4) <> "6999" Then
                            'Write the "5442" line to the file.
                        objFile.WriteLine(arrFileText(i))
                    End If
                Else
                        'If the next line does not exist, write the "5442" line to the file (without a new line).
                    objFile.WriteLine(arrFileText(i))
                End If              
                'If the line does not start with "6999" and the line does not start with "7999".
            Elseif Left(arrFileText(i),4) <> "6999"  AND Left(arrFileText(i),4) <> "7999" Then
                    'Write the line to the file.
                objFile.WriteLine(arrFileText(i))
            End If
        End If
    Next
        'Close the file.
    objFile.Close
    Set objFile = Nothing
End Sub

Sub RemoveBlankLines(strInputFile)
    Set objFile = CreateObject("Scripting.FileSystemObject").OpenTextFile(strInputFile,1)
        'Read the entire file into memory.
    strFileText = objFile.ReadAll
        'Close the file.
    objFile.Close
        'Split the file at the new line character.
    arrFileText = Split(strFileText,VbNewLine)
    Set objFile = CreateObject("Scripting.FileSystemObject").OpenTextFile(strInputFile,2,true)
        'Loop through the array of lines looking for lines to keep.
    For i = LBound(arrFileText) to UBound(arrFileText)
            'If the line is not blank.
        if arrFileText(i) <> "" Then
                'If there is another element.
            if i + 1 <= UBound(arrFileText) Then    
                    'If the next element is not blank.
                if arrFileText(i + 1) <> "" Then
                        'Write the line to the file.
                    objFile.WriteLine(arrFileText(i))
                Else
                        'Write the line to the file (Without a blank line).
                    objFile.Write(arrFileText(i))
                End If
            Else
                    'Write the line to the file (Without a blank line).
                objFile.Write(arrFileText(i))
            End If
        End If
    Next
    'Close the file.
    objFile.Close
    Set objFile = Nothing
End Sub 

Чтобы использовать его, вызовите его из командной строки одним из двух способов.

RemoveUnwantedLines "C:\TestDirectory\" "C:\Output.txt"

или

RemoveUnwantedLines "C:\TestDirectory\"
1 голос
/ 23 июня 2010

Я думаю, что это сработает (но я не так хорош в VBS, поэтому никаких обещаний):

Set objFS = CreateObject("Scripting.FileSystemObject")
strFile = "c:\temp\file.100621"
Set objFile = objFS.OpenTextFile(strFile)
Dim cachedLine
Do Until objFile.AtEndOfStream
    strLine = objFile.ReadLine

    If Len(cachedLine) > 0 And InStr(strLine,"6999") = 1 Then
         WScript.Echo cachedLine        
    End If
    cachedLine = ""

    If InStr(strLine,"5442") = 1 Then
        cachedLine = strLine
    Else
        If InStr(strLine,"6999") = 1 Or InStr(strLine,"7999") = 1 Then
            ' do nothing
        Else
            WScript.Echo strLine        
        End If
    End If     
Loop

Обратите внимание, что я думаю, что вы проверяли, содержали ли строки числа где-либо, но вы сказали, что правило было, если они начинались с цифр, поэтому я делаю <> 1 вместо > 0.

0 голосов
/ 24 июня 2010

ОК, вот последний скрипт, собранный Tester101.Этот скрипт удаляет ненужные строки, как описано выше.Он также касается строк, которые находятся в конце каждой строки (мне неизвестно)

Select Case Wscript.Arguments.Count
case 1:
    strInput = GetFile(WScript.Arguments(0))
    RemoveUnwantedLines strInput, strInput
    RemoveBlankLines strInput
case 2:
    strInput = GetFile(WScript.Arguments(0))
    strOutput = Wscript.Arguments(1)
    RemoveUnwantedLines strInput, strOutput
    RemoveBlankLines strOutput
End Select

Function GetFile(strDirectory)
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFolder = objFSO.GetFolder(strDirectory)
dateLastModified = Null
strFile = ""
For Each objFile in objFolder.Files
    If IsNull(dateLastModified) Then
        dateLastModified = objFile.DateLastModified
        strFile = objFile.Path
    ElseIf dateLastModified < objFile.DateLastModified Then
        dateLastModified = objFile.DateLastModified
        strFile = objFile.Path
    End If
Next
GetFile = strFile
End Function

Sub RemoveUnwantedLines(strInputFile, strOutputFile)
    'Open the file for reading.
    Set objFile = CreateObject("Scripting.FileSystemObject").OpenTextFile(strInputFile,1)
    'Read the entire file into memory.
    strFileText = objFile.ReadAll
    'Close the file.
     objFile.Close
    'Split the file at the new line character. *Use the Line Feed character (Char(10))
    arrFileText = Split(strFileText,Chr(10))
    'Open the file for writing.
    Set objFile = CreateObject("Scripting.FileSystemObject").OpenTextFile(strOutputFile,2,true)
    'Loop through the array of lines looking for lines to keep.
    For i = LBound(arrFileText) to UBound(arrFileText)
        'If the line is not blank process it.
        If arrFileText(i) <> "" Then
            'If the line starts "5442", see if the next line is "6999".
            If Left(arrFileText(i),4) = "5442" Then
                'Make sure the next line exists (Don't want an out of bounds exception).
                If i + 1 <= UBound(arrFileText)Then
                    'If the next line is not "6999" 
                    If Left(arrFileText(i + 1), 4) <> "6999" Then
                        'Write the "5442" line to the file.
                        objFile.WriteLine(arrFileText(i))
                    End If
                Else
                    'If the next line does not exist, write the "5442" line to the file (without a new line).
                    objFile.WriteLine(arrFileText(i))
                End If              
            'If the line does not start with "6999" and the line does not start with "7999".
            Elseif Left(arrFileText(i),4) <> "6999"  AND Left(arrFileText(i),4) <> "7999" Then
                'Write the line to the file.
                objFile.WriteLine(arrFileText(i))
            End If
        End If
Next
    'Close the file.
objFile.Close
Set objFile = Nothing
End Sub

Sub RemoveBlankLines(strInputFile)
Set objFile = CreateObject("Scripting.FileSystemObject").OpenTextFile(strInputFile,1)
    'Read the entire file into memory.
strFileText = objFile.ReadAll
    'Close the file.
objFile.Close
    'Split the file at the new line character.
arrFileText = Split(strFileText,VbNewLine)
Set objFile = CreateObject("Scripting.FileSystemObject").OpenTextFile(strInputFile,2,true)
    'Loop through the array of lines looking for lines to keep.
For i = LBound(arrFileText) to UBound(arrFileText)
        'If the line is not blank.
    if arrFileText(i) <> "" Then
            'If there is another element.
        if i + 1 <= UBound(arrFileText) Then    
                'If the next element is not blank.
            if arrFileText(i + 1) <> "" Then
                    'Write the line to the file.
                objFile.WriteLine(arrFileText(i))
            Else
                    'Write the line to the file (Without a blank line).
                objFile.Write(arrFileText(i))
            End If
        Else
                'Write the line to the file (Without a blank line).
            objFile.Write(arrFileText(i))
        End If
    End If
Next
'Close the file.
objFile.Close
Set objFile = Nothing
End Sub 
0 голосов
/ 24 июня 2010

Это был бы мой псевдоалгоритм для решения этой проблемы:

(я скорее научу вас своим мыслям о том, как я могу решить эту проблему, чем предоставлю сам код)

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

  2. Сделать простой файл «config» и для этой программы,Каждая строка может представлять «фильтр», и позже вы также можете добавить действия к строкам, если необходимо.

    7999 delete

    6999 delete

    5442 delete

    как в [pattern] [action]

  3. Теперь после считывания конфигурации в массив «ключей», затем проверьте «Входящие» на наличие файлов.Для каждого файла обработайте его с помощью набора ключей.

  4. Обработка файла "XXXXXXXXX.log" (или любого другого имени) Загрузите все строки, если их не слишком много или readline, чтобы захватитьодин (в зависимости от производительности и использования памяти)

  5. Для каждой строки взять первые 4 буквы из строки ...

Сейчаснам понадобится строка для разбора:

sLine = left(readline(input filestream), 4) 

, так как нам нужно только первые 4 символа, чтобы решить, нужно ли нам его сохранить.

Если эта "sLine" (строка) находится внаш массив фильтров / шаблонов, тогда у нас есть совпадение совпадений ... выполните то действие, которое мы настроили (в текущей настройке - delete = игнорировать строку).

6a.Если игнорировать, перейдите к следующей строке в текстовом файле, перейдите к # 7

6b.Если в массиве шаблонов нет совпадений, у нас есть строка для сохранения.Запишите это в поток OUTPUT.

Если больше строк, СЛЕДУЮЩАЯ (перейдите к # 5)

Закрыть файл ввода и вывода.

Удалить / переместить вводфайл из папки «Входящие» (возможно, для резервного копирования?)

Если в каталоге [inbox] больше файлов, то выполнить следующий анализ ... перейти к # 4

Это не просто VBSCRIPT, а идея алгоритма для любого языка ...

Я надеюсь, что вы можете увидеть мою идею в ней, иначе вы просто прокомментируете ее, а я постараюсь уточнить ее.Надеюсь, я сделал тебе отличный ответ.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...