Если вы не возражаете, мне нужна помощь со скриптом извлечения, который у меня есть
Этот скрипт работает отлично и быстро, пока мой текстовый файл не превышает 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, сделают эту работу очень легко, но вся моя рабочая станция работает с пакетными скриптами, поэтому я стараюсь придерживаться пакетного режима
Любая помощь будет принята с благодарностью
Спасибо за идею, но у нас получился пакетный скрипт, работающий общее время на извлечение 1 минуту
@Compo: я недостаточно знаю PowerShell, чтобы знать, какой код выполняет это извлечение ряда полей. Или это должно выполняться через цикл? Спасибо...
https://superuser.com/questions/1605009/windows-command-line-find-command-is-very-slow
^ Обратитесь сюда, если это поможет ^
Моя рекомендация:
Попробуйте использовать findstr
вместо find
, который вы использовали для поиска строк. Я видел в одной статье, что это быстрее, чем команда find
, так как команда find старше и медленнее.
Я не понимаю, как вашу команду powershell можно использовать для извлечения строк между «именем» и «кау», включая их, как запросил OP («извлечение между ключевыми словами»). Не могли бы вы лучше объяснить этот момент?
Я подумал, что findster
был ответом, но не знал, как преобразовать мой скрипт в findster.
замените команду find
, которую вы использовали в своем сценарии, на findstr
и оставьте другие сценарии такими же. Должно сработать, попробуй.
Два комментария к вашему коду:
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"...
Нет. Выполните эту команду из командной строки: findstr /N "name caow" "%sourcedir%\nsb.txt"
. На выходе должно быть всего 2 строки: строки с «name» и «caow». Если нет, то проблема с вашими данными...
Создайте новый скрипт всего из двух строк: findstr /N "name caow" "%sourcedir%\nsb.txt"
в одной и pause
во второй строке. Затем запустите его и сообщите результат...
Прошу прощения. Я не смогу вам помочь, если вы не поможете мне обнаружить проблему...
Я предполагаю, что в вашем файле данных есть более одной строки со значением "caow"
! Однако, если вы не подтвердите этот пункт, я не смогу исправить свой код... :(
Ммм... Я думаю, что не смог вам помочь, потому что вы не даете мне обратной связи, которую я просил раньше, чтобы помочь вам... Я просил вас 3 раза ( здесь , следующий комментарий под ним и ️ 🔁 вот ) которую ты исполняешь findstr /N "name caow" "%sourcedir%\nsb.txt"
и просто проигнорил меня...
Хорошо. Если вы ответили на мою просьбу так, как вы сказали (не то, что вы думаете, я должен знать, а простой и четкий запрос: выполнить findstr /N "name caow" "%sourcedir%\nsb.txt"
), пожалуйста, скажите мне, где выход такой findstr
команды... Приглашаю вас прочитать комментарии выше еще раз, прежде чем ответить на это...
Не уверен, где вы хотите, чтобы я сообщил о результатах, но я добавил больше материала к моему ответу, который я разместил ниже, - если это не то, что вы хотите увидеть, - тогда я понятия не имею, о чем вы спрашиваете - если я ошибся, тогда спасибо за ваше время
Вот как я настроил извлечение между двумя словами
@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>
Используйте PowerShell, который полностью поддерживает JSON, а не внутренние команды cmd.exe, которые этого не делают.