Извлечение конкретных полей из многострочного текстового файла с помощью пакетного файла (.BAT)

Вопрос или проблема

Я новичок в пакетном программировании, и моя жена попросила меня помочь ей ускорить её работу. Вопрос: как мне извлечь дату, номер терминала (00099106), сумму транзакции и комиссию из этого образца текстового файла?

[4w                                                    ИСТОРИЯ ДЕЯТЕЛЬНОСТИ POS ТЕРМИНАЛА
                                                  ДЛЯ КРЕДИТНОГО НОМЕРА СЧЕТА: 1120162163
Номер отчета: BDO030114                                                                                                              Страница 1
Дата бизнеса: 03/02/2015                                                                                      Дата формирования: 03/03/2015
=========================================================================================================================================
   ТРАНЗАКЦИЯ   |    ТЕРМИНАЛ    |      |        КАРТА        |      СЧЕТ      |   ТРАНЗАКЦИЯ   | РЕЗУЛЬТ. | АВТОРИЗ. | РЕВ | СООБЩ. |  ТОРГОВЕЦ  
  ДАТА  |  ВРЕМЯ  |   НОМ.  | ЧЕК | НОМ. BR |       НОМЕР       |        НОМ.         | КОД |   СУММА   | КОД | МЕТОД | ИНД | ТИП |   ДОЛЯ    
=========================================================================================================================================
03/01/15 23:54:30 00099106     203  00695 6018530000004863     ************          00      2,250.00   0      1        210               
               ===================================================================================================
                                   | ТОВАР КАРТЫ  | КОЛИЧЕСТВО |       СУММА       |  КОМИССИЯ  |
               ===================================================================================================
                                       00099106 SMARTELLER            1             2,250.00                
                                00099106 ИТОГО:                       1             2,250.00                

                                       ТОРГОВЕЦ SMARTELLER            1             2,250.00          33.75 
                              ИТОГО ТОРГОВЦА:                       1             2,250.00          33.75 

                            ИТОГО ЗА ПОКУПКУ:                       1             2,250.00          33.75 

                            ИТОГО ПО ТОРГОВЦУ:                       1             2,250.00          33.75 

[4w

Вывод должен выглядеть так

03/02/2015;00099106;2,250.00;33.75

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

Мне кажется, что ваша дата следует за “Дата бизнеса: ” в начале строки.

Номер терминала следует за “nn/nn/nn nn:nn:nn ” (дата и время) в начале строки.

Вы неясно указываете, какую сумму или комиссию вы хотите. Я предположу, что вы хотите значения, которые следуют за “ИТОГО ПО ТОРГОВЦУ:”

Получить информацию с помощью чистого пакетного скрипта довольно легко.

Для этого примера я предполагаю, что текст находится в файле с именем test.txt.

Команда FINDSTR может искать 3 строки, содержащие ваши данные, используя примитивные регулярные выражения. Опция /R обрабатывает поиски как регулярные выражения. Я использую отдельную опцию /C:"строка поиска", чтобы указать каждую строку поиска, содержащую пробелы. При поиске строки, начинающейся с даты и времени, я решил просто искать слэш и двоеточия с соответствующим количеством символов между ними.

Команда FOR /F анализирует три строки вывода FINDSTR, по одной строке за раз. По умолчанию она обрабатывает пробелы и табуляции как разделители токенов. Строка последовательных пробелов рассматривается как один разделитель. Таким образом, как дата, так и номер терминала являются третьим токеном в строке. Ваша сумма и комиссия являются пятым и шестым токенами в строке.

Поэтому я явно запрашиваю 3-й, 5-й и 6-й токены каждой строки, указывая %%A как первый захваченный токен. Это означает, что 3-й токен будет в %%A, 5-й в %%B, а 6-й в %%C.

Я явно обнуляю переменные dt и term. Строки всегда появляются в одном и том же порядке, поэтому я просто проверяю, определена ли dt. Если нет, то это первая строка, и я устанавливаю значение даты. В противном случае я проверяю, определена ли term. Если нет, то это должна быть вторая строка, и я устанавливаю значение терминала. В противном случае это должна быть третья строка, и я устанавливаю значения суммы и комиссии.

@echo off
setlocal
set "dt="
set "term="
for /f "tokens=3,5,6" %%A in (
  'findstr /rc:"^Дата бизнеса:" /c:"^../../.. ..:..:.." /c:"ИТОГО ПО ТОРГОВЦУ:" test.txt'
) do (
  if not defined dt (
    set "dt=%%A"
  ) else if not defined term (
    set "term=%%A"
  ) else (
    set "amt=%%B"
    set "comm=%%C"
  )
)
echo %dt%;%term%;%amt%;%comm%

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

Я написал JREPL.BAT – гибридный утилиту JScript/пакет, которая может очень эффективно выполнять сложные операции поиска/замены с регулярными выражениями над текстом. JREPL.BAT – это чистый скрипт, который работает нативно на любой Windows машине начиная с XP. Полная документация встроена в утилиту. Она доступна, если ввести jrepl /?. Вы можете использовать jrepl /?|more, если хотите посмотреть помощь по одной странице за раз.

Предположим, что у вас есть JREPL.BAT где-то в вашем PATH, тогда следующее извлечет информацию:

@echo off
call jrepl "[\s\S]*\nДата бизнеса: (.*?) (?:.*\n){5}.*? .*? (.*?) [\s\S]*?ИТОГО ПО ТОРГОВЦУ: +.*? +(.*?) +([^ ]*)[\s\S]*" "$1;$2;$3;$4" /m /f test.txt
echo(

convert.cmd:

powershell .\convert.ps1

powershell convert.ps1:

$head=3
$f=gc data.txt
$f[$head..($f.count-1)]|%{
if($_.Contains("Дата бизнеса:"   )){$s=$_.split(': ')[3]};
if($_.Contains("ИТОГО ТОРГОВЦА:")){$MT=($_.trim()-replace'\s+',' ').split(' ');$s=$s+';'+$MT[-2]+';'+$MT[-1]};
if($_.Contains("SMARTELLER"       )){$SM=($_.trim()-replace'\s+',' ').split(' ');if($SM[0] -ne "ТОРГОВЕЦ"){$s=$s+';'+$SM[0]} };
} 
$s|ac short.txt

Вариант 2:

$f=gc data.txt
$s=$f[(3)].Substring(15,10)+';'+$f[(8)].Substring(18,8)+';'
$head=15
$f[$head..($f.count-1)]|%{if($_.Contains("ИТОГО ТОРГОВЦА:")){$MT=($_.trim()-replace'\s+',' ').split(' ');$s=$s+$MT[-2]+';'+$MT[-1]}} 
$s|ac short.txt

Вариант 3:

$f=gc data.txt
$s=$f[(3)].Substring(15,10)+';'+$f[(8)].Substring(18,8)+';'+($f[(16)].Substring(80,15)).Trim()+';'+$f[(16)].Substring(102,5)|ac short.txt

Ответ или решение

Ниже приведен полный ответ на вопрос о том, как извлечь конкретные поля из многострочного текстового файла с помощью пакетного файла (.BAT). Я опишу разносторонний подход и предоставлю пример кода.

Решение задачи с помощью пакетного файла (.BAT)

Для извлечения необходимых данных из текстового файла вам потребуется использовать команду FINDSTR для поиска определенных строк, а затем команду FOR /F для обработки результата. В данном примере мы будем извлекать дату бизнеса, номер терминала, сумму транзакции и комиссию из файла test.txt.

Пример кода .BAT

@echo off
setlocal

rem Инициализация переменных
set "dt="
set "term="
set "amt="
set "comm="

rem Обработка файла посредством поиска нужных строк
for /f "tokens=3,5,6" %%A in (
  'findstr /rc:"^Business Date:" /c:"^../../.. ..:..:.." /c:"TOTAL PER MERCHANT:" test.txt'
) do (
  if not defined dt (
    set "dt=%%A"
  ) else if not defined term (
    set "term=%%A"
  ) else (
    set "amt=%%B"
    set "comm=%%C"
  )
)

rem Форматирование даты
set "dt=%dt:~0,10%"

rem Вывод извлеченных данных
echo %dt%;%term%;%amt%;%comm%

Объяснение кода

  1. Инициализация переменных: Мы создаем пустые строки для хранения даты, номера терминала, суммы и комиссии.

  2. Поиск строк: Используем команду FINDSTR с параметрами:

    • /R для регулярных выражений.
    • /C для точного поиска строк.
      Мы ищем строки, содержащие "Business Date:", текущую дату и "TOTAL PER MERCHANT:".
  3. Обработка строк: Команда FOR /F позволяет нам циклически обрабатывать каждую найденную строку. tokens=3,5,6 указывает, какие токены мы хотим извлечь. В зависимости от того, какая переменная еще не была определена, мы присваиваем соответствующие значения.

  4. Форматирование даты: Мы обрезаем дату до нужного формата.

  5. Вывод: Наконец, выводим извлеченные данные в нужном формате.

Альтернативный подход

Если вы хотите использовать более мощный инструмент, такой как JREPL.BAT (гибридный JScript/BAT), вы можете обрабатывать текст более эффективно с помощью регулярных выражений.

Пример кода с использованием JREPL.BAT

@echo off
call jrepl "[\s\S]*\nBusiness Date: (.*?) (?:.*\n){5}.*? .*? (.*?) [\s\S]*?TOTAL PER MERCHANT: +.*? +(.*?) +([^ ]*)[\s\S]*" "$1;$2;$3;$4" /m /f test.txt
echo(

Заключение

Выше представлены два подхода к решению вашей задачи: один с использованием стандартного пакетного файла и второй с использованием расширенных возможностей JREPL.BAT для работы с регулярными выражениями. Оба подхода позволят вам извлечь необходимые поля из текстового файла, обеспечив гибкость и контроль над предварительной обработкой данных.

Оцените материал
Добавить комментарий

Капча загружается...