Как извлечь между ключевыми словами, используя пакет

Если вы не возражаете, мне нужна помощь со скриптом извлечения, который у меня есть
Этот скрипт работает отлично и быстро, пока мой текстовый файл не превышает 100 тысяч строк
Файл, который я тестировал, имеет 60 000 строк и представляет собой формат Json
, и он отлично работает
но когда я протестировал его на текстовом файле размером более 500 КБ, это заняло очень много времени,
туда, где я только что закрыл окно CMD

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

Вот мой сценарий

@ECHO OFF
SETLOCAL 

SET "sourcedir=%~dp0New folder 1"
SET "destdir=%~dp0New folder 2"

for /f "tokens=1 delims=[]" %%a in ('find /n "name"^<"%sourcedir%\nsb.txt" ') do set /a start=%%a
for /f "tokens=1 delims=[]" %%a in ('find /n "caow"^<"%sourcedir%\nsb.txt" ') do set /a end=%%a
(
for /f "tokens=1* delims=[]" %%a in ('find /n /v ""^<"%sourcedir%\nsb.txt" ') do (
 IF %%a geq %start% IF %%a leq %end% ECHO(%%b
 )
)>"%destdir%\(1).txt"
GOTO :EOF

Это малая часть содержимого файлов

  {
  "name": 6,
  "agprlv": 0,
  "las": "ACTIVE",
  "gdprcs": "Consented",
  "gdprcds": true,
  "gdprcpv": 2,
  "ccpacltc": 0,
  "ccpacs": false,
  "ccpaoov": "control",
  "pdcs": false,
  "moptinfcs": 0,
  "moptinnour": false,
  "moptintlact": -1,
  "boqt": 4.033,
  "boht": 6.819,
  "tdtr": 43026170.0,
  "tplt": 184592,
  "tgrt": 126002,
  "dbdt": 1,
  "dbla": 89,
  "dbir": 429,
  "dblt": 1648640442000,
  "odbct": "03/30/2022 11:41:10",
  "mgpl": 50654349249,
  "mgat": 0,
  "lblt": "05/18/2022 05:00:00",
  "lbct": "04/06/2022 05:00:00",
  "cert": "05/14/2022 00:00:00",
  "lpff": "12/31/9999 23:59:59",
  "caow": [
    {

Я хотел бы поделиться всем текстовым файлом, но я не могу
текущий текстовый файл имеет 566857 строк
Мои файлы состоят из трех частей верхняя половина начинается с 1 и заканчивается на 20K
средняя часть начинается с 20001 и заканчивается на 460К
нижняя половина начинается с 460001 и с 566К

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

Любая помощь будет принята с благодарностью

Используйте PowerShell, который полностью поддерживает JSON, а не внутренние команды cmd.exe, которые этого не делают.

Compo 06.01.2023 01:03

Спасибо за идею, но у нас получился пакетный скрипт, работающий общее время на извлечение 1 минуту

JR Santos 06.01.2023 23:19

@Compo: я недостаточно знаю PowerShell, чтобы знать, какой код выполняет это извлечение ряда полей. Или это должно выполняться через цикл? Спасибо...

Aacini 07.01.2023 02:50
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
3
83
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

https://superuser.com/questions/1605009/windows-command-line-find-command-is-very-slow
^ Обратитесь сюда, если это поможет ^


Моя рекомендация: Попробуйте использовать findstr вместо find, который вы использовали для поиска строк. Я видел в одной статье, что это быстрее, чем команда find, так как команда find старше и медленнее.

Я не понимаю, как вашу команду powershell можно использовать для извлечения строк между «именем» и «кау», включая их, как запросил OP («извлечение между ключевыми словами»). Не могли бы вы лучше объяснить этот момент?

Aacini 06.01.2023 04:37

Я подумал, что findster был ответом, но не знал, как преобразовать мой скрипт в findster.

JR Santos 06.01.2023 23:20

замените команду find, которую вы использовали в своем сценарии, на findstr и оставьте другие сценарии такими же. Должно сработать, попробуй.

tabby.sl 07.01.2023 03:03
Ответ принят как подходящий

Два комментария к вашему коду:

  • Старайтесь выполнять как можно меньше операций. Вы выполняете две команды IF в каждой строке большого файла!
  • Команда FOR /F сначала выполняет команды и сохраняет во временном файле все выходные данные. Если вывод большой, необходимо выделить дополнительные буферы и т. д. Когда команда вывода завершается, FOR /F начинает выводить свои данные из временного файла out. Следствие: никогда не используйте команду FOR /F для больших файлов.

Попробуйте это решение:

@ECHO OFF
SETLOCAL EnableDelayedExpansion

SET "sourcedir=%~dp0New folder 1"
SET "destdir=%~dp0New folder 2"

set "skip = "
for /F "delims=:" %%a in ('findstr /N "name caow" "%sourcedir%\nsb.txt"') do (
   if not defined skip (
      set /A "skip=%%a-1"
   ) else (
      set /A "copy=%%a-skip+1"
   )
)

< "%sourcedir%\nsb.txt" (

   rem Skip undesired lines at beginning
   for /L %%i in (1,1,%skip%) do set /P " = "

   rem Copy desired lines
   for /L %%i in (1,1,%copy%) do (
      set /P "line = "
      echo(!line!
   )

) > "%destdir%\(1).txt"
GOTO :EOF

Пожалуйста, сообщите время...

Пожалуйста, сообщите вывод этой команды: findstr /N "name caow" "%sourcedir%\nsb.txt". Это должны быть строки тегов "name" и "caow"...

Aacini 06.01.2023 04:41

Нет. Выполните эту команду из командной строки: findstr /N "name caow" "%sourcedir%\nsb.txt". На выходе должно быть всего 2 строки: строки с «name» и «caow». Если нет, то проблема с вашими данными...

Aacini 06.01.2023 04:47

Создайте новый скрипт всего из двух строк: findstr /N "name caow" "%sourcedir%\nsb.txt" в одной и pause во второй строке. Затем запустите его и сообщите результат...

Aacini 06.01.2023 04:55

Прошу прощения. Я не смогу вам помочь, если вы не поможете мне обнаружить проблему...

Aacini 06.01.2023 05:00

Я предполагаю, что в вашем файле данных есть более одной строки со значением "caow"! Однако, если вы не подтвердите этот пункт, я не смогу исправить свой код... :(

Aacini 06.01.2023 05:09

Ммм... Я думаю, что не смог вам помочь, потому что вы не даете мне обратной связи, которую я просил раньше, чтобы помочь вам... Я просил вас 3 раза ( здесь , следующий комментарий под ним и ️ 🔁 вот ) которую ты исполняешь findstr /N "name caow" "%sourcedir%\nsb.txt" и просто проигнорил меня...

Aacini 20.01.2023 23:21

Хорошо. Если вы ответили на мою просьбу так, как вы сказали (не то, что вы думаете, я должен знать, а простой и четкий запрос: выполнить findstr /N "name caow" "%sourcedir%\nsb.txt"), пожалуйста, скажите мне, где выход такой findstr команды... Приглашаю вас прочитать комментарии выше еще раз, прежде чем ответить на это...

Aacini 21.01.2023 03:54

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

JR Santos 21.01.2023 04:12

Вот как я настроил извлечение между двумя словами

    @ECHO OFF
    SETLOCAL EnableDelayedExpansion
    
    SET "sourcedir=%~dp0New folder 1"
    SET "destdir=%~dp0New folder 2"
    
    set "skip = "
    for /F "delims=:" %%a in ('findstr /N "<\name\>" "%sourcedir%\nsb.txt"') do (
       if not defined skip (
          set /A "skip=%%a-1"
       ) else (
          set /A "copy=%%a-skip"
       )
    )
    for /F "delims=:" %%a in ('findstr /N "<\caow\>" "%sourcedir%\nsb.txt"') do (
       if not defined skip (
          set /A "skip=%%a"
       ) else (
          set /A "copy=%%a-skip-1"
       )
    )
    
    < "%sourcedir%\nsb.txt" (
    
       rem Skip undesired lines at beginning
       for /L %%i in (1,1,%skip%) do set /P " = "
    
       rem Copy desired lines
       for /L %%i in (1,1,%copy%) do (
          set /P "line = "
          echo(!line!
       )
    
    ) > "%destdir%\(1).txt"
    GOTO :EOF

после использования обновленного скрипта выше, где мои результаты
если ваш поиск повторяется вот так "name": or "funname" вы можете сделать это, чтобы заблокировать его "<\name\>"

Но если у вас есть два повторяющихся слова, таких как это "name": и это "name":, он найдет любое из них и извлечет неправильно

Output Results..... <br>

 {
  "name": 6,
  "agprlv": 0,
  "las": "ACTIVE",
  "gdprcs": "Consented",
  "gdprcds": true,
  "gdprcpv": 2,
  "ccpacltc": 0,
  "ccpacs": false,
  "ccpaoov": "control",
  "pdcs": false,
  "moptinfcs": 0,
  "moptinnour": false,
  "moptintlact": -1,
  "boqt": 4.033,
  "boht": 6.819,
  "tdtr": 43026170.0,
  "tplt": 184592,
  "tgrt": 126002,
  "dbdt": 1,
  "dbla": 89,
  "dbir": 429,
  "dblt": 1648640442000,
  "odbct": "03/30/2022 11:41:10",
  "mgpl": 50654349249,
  "mgat": 0,
  "lblt": "05/18/2022 05:00:00",
  "lbct": "04/06/2022 05:00:00",
  "cert": "05/14/2022 00:00:00",
  "lpff": "12/31/9999 23:59:59",

The script runs great but it also depends on the size of the file <br>
working on a 556K file it took 2 minutes to extract data and again it depends on the size of the file <br>

Другие вопросы по теме