Вопрос или проблема
У меня есть текстовый файл (epin.txt) с более чем 2 миллионами строк.
Пример текста:
182060045892569246925460002021 03560000000020000840000000000000ABDRGS00IN0000MMFADT265000 0917 P81 001
182060045892585476932540002021 03560000000100000356000000000000PFTSVS00IN0000MMTHRD285000 0997 P81 001
182071045892585476932540002021 03560000006905000356000000000000DFRTSS00IN0000BPSYFZ865000 0006 P81 001
Я хочу извлечь только те строки, где в 4-й, 5-й, 6-й и 7-й колонках находятся “0600”, “0610”, “0620”, в новый текстовый файл.
Таким образом, из примера нужно извлечь только 1-ю и 2-ю строки в новый файл:
182060045892569246925460002021 03560000000020000840000000000000ABDRGS00IN0000MMFADT265000 0917 P81 001
182060045892585476932540002021 03560000000100000356000000000000PFTSVS00IN0000MMTHRD285000 0997 P81 001
Мне удалось сделать это с помощью Excel, но только с файлами, содержащими менее 1 миллиона строк.
Затем я попробовал использовать FINDSTR:
findstr /B "0600 0610 0620" epin.txt > rf.txt
Но это работало только для строк, начинающихся с 0600, 0610 или 0620; и только с конкретным именем файла.
Можно ли немного улучшить, чтобы поиск осуществлялся по заданным фразам, начиная с N-го символа, и в любых текстовых/CSV/плоских файлах (например, используя подстановочный знак в имени файла в коде epin***.txt)?
Попробуйте замену символов (по одному разу/колонке), в Findstr
:
String: 1820600
Заменить: 182 на: ...0600
И вы можете использовать .
, чтобы указать поиск в нужной колонке в команде Findstr
.
findstr /B "...0600 ...0610 ...0620" epin.txt > rf.txt
Для нескольких файлов я предлагаю цикл с использованием какого-то механизма, как:
for /f ('где current_folder:file.txt + current_folder:file???.txt')do findstr ...
- Ваш код (в командной строке) будет выглядеть так:
cd /d "Диск:\Полный\Путь\К\Папке\Файлов" & for /f delims^= %i in ('%__AppDir__%Where.exe .:epin.txt .:epin???.txt')do <con: %__AppDir__%Findstr.exe /b "...0600 ...0610 ...0620" "%~i">>rf.txt
- Ваш код (в batch-файле) будет выглядеть так:
@echo off
cd /d "Диск:\Полный\Путь\К\Папке\Файлов"
for /f delims^= %%i in ('%__AppDir__%Where.exe .:epin.txt .:epin???.txt
')do <con: %__AppDir__%Findstr.exe /b "...0600 ...0610 ...0620" "%%~i">>rf.txt
Примечание 1: Прошу прощения за мой ограниченный английский, надеюсь, вы поймете ответ/код..
Примечание 2: Я не совсем понял эту часть:
Можно ли немного улучшить, чтобы поиск осуществлялся по заданным фразам, начиная с N-го символа, и в нескольких файлах (например, epin001.txt, epin002.txt и т.д.)?
- Ниже приведено предложение, которое будет подсчитывать файлы в
epin???.txt
в циклеFor /F
, и использовать результат%%~i
в цикле по диапазону чисел, начиная с 1 и увеличивая на 1 к общему числу, найденному в%%~i
, и запускать фильтрациюFindstr
в порядке/диапазоне001-00%%~i
:
@echo off
Setlocal EnableDelayedExpansion
cd /d "D:\Полный\Путь\К\Папке\."
>nul 2>&1 del /q /f /a: .\rf.txt
for /f %%i in ('dir /b epin*.txt^|%__AppDir__%Find.exe /v /c ""'
)do for /l %%L in (1 1 %%~i)do set "_n=00%%~L" && call %:^) !_n:~-3!
%:^)
if "%~1"=="" (
endlocal & goto :eOf ) else 2>nul (
<con: %__AppDir__%Findstr.exe /b "...0600 ...0610 ...0620" ".\epin%~1.txt" >>rf.txt
;exit /b )
Учитывая ваш последний комментарий и также последнее редактирование в вашем вопросе…
Можно ли немного улучшить, чтобы поиск осуществлялся по заданным фразам, начиная с N-го символа, и в любых текстовых/CSV/плоских файлах (например, используя подстановочный знак в имени файла в коде epin**.txt)?*
Да
Я могу предложить искать с помощью Findstr
в колонке (или начиная с определенной колонки), используя точки в таком же количестве символов/колонок, или один или несколько символов такой формы (.*
).
.*
Таким образом, заменяя 1
символ (.
) или больше
символов (*
).
@echo off
cd /d "D:\Полный\Путь\К\Папке\."
>nul 2>&1 del /q /f /a: .\rf.txt
set "_my_files=.:*.csv .:*.flat .:epin*.txt"
set "_30th_column=.............................."
set "_find_in_30th=%_30th_column%0600 %_30th_column%0610 %_30th_column%0620"
for /f %%i in ('%__AppDir__%Where.exe %_my_files%
')do <con: %__AppDir__%Findstr.exe /b "%_find_in_30th%" "%~i">>rf.txt
Дополнительные ресурсы:
Where
For /?
For /F
Findstr
- Перенаправление
|
,<
,>
,2>
и т.д.
Goto :Label
|Call :Label
If condition() else condition()
- DOS – Манипуляция строками // dostips.com
- Недокументированные переменные :
- Как Windows Command Interpreter [
cmd.exe
] парсит скрипты - Как можно передать аргументы в пакетный файл | также относится к функции
Ответ или решение
Чтобы извлечь строки с определённой фразой в указанном столбце из текстового файла в Windows с помощью пакета команд (batch file), вы можете использовать утилиту findstr
, поскольку она предоставляет необходимые возможности для фильтрации строк. В данном случае, мы хотим извлечь строки из файла epin.txt
, где определённые значения (0600, 0610, 0620) находятся в 4, 5, 6 или 7 столбцах.
Шаги для реализации:
-
Подготовка файла: Убедитесь, что ваш файл
epin.txt
находится в доступном месте на вашем компьютере. -
Создание пакетного файла: Откройте любой текстовый редактор (например, Блокнот) и создайте новый файл с расширением
.bat
, напримерextract_rows.bat
. -
Скрипт для извлечения: Вставьте следующий код в созданный файл:
@echo off
setlocal enabledelayedexpansion
rem Укажите путь к директории, где находится epin.txt
cd /d "C:\Путь\К\Директории"
rem Удалите существующий файл rf.txt, если он есть
if exist rf.txt del rf.txt
rem Определите паттерны поиска
set "pattern=...0600 ...0610 ...0620"
rem Ищем в epin.txt и записываем результат в rf.txt
findstr /B "%pattern%" epin.txt >> rf.txt
echo Задача завершена. Извлеченные строки сохранены в rf.txt.
Объяснение кода:
@echo off
— командный интерпретатор не будет показывать команды в процессе выполнения.setlocal enabledelayedexpansion
— позволяет использовать расширенные переменные в циклах и других конструкциях.cd /d "C:\Путь\К\Директории"
— меняет текущую директорию на ту, где находится текстовый файл. ЗаменитеC:\Путь\К\Директории
на фактический путь к вашей директории.if exist rf.txt del rf.txt
— проверяет существует ли файлrf.txt
и удаляет его, чтобы избежать добавления результатов в старый файл.set "pattern=...0600 ...0610 ...0620"
— задает паттерны для поиска строк, содержащих указанные значения, начинать с определённых позиций в строке.findstr /B "%pattern%" epin.txt >> rf.txt
— выполняет поиск по файлуepin.txt
с заданными паттернами и записывает результат вrf.txt
.- В конце выводит сообщение о завершении операции.
Дополнительные возможности:
Если вы хотите обрабатывать множество файлов и использовать шаблоны для поиска с расширением, можно расширить скрипт для обработки всех файлов, соответствующих паттерну. Например:
@echo off
setlocal enabledelayedexpansion
cd /d "C:\Путь\К\Директории"
if exist rf.txt del rf.txt
set "pattern=...0600 ...0610 ...0620"
rem Обработка всех файлов epin*.txt
for %%i in (epin*.txt) do (
findstr /B "%pattern%" "%%i" >> rf.txt
)
echo Задача завершена. Извлеченные строки сохранены в rf.txt.
Заключение
Использование пакетных файлов и командной строки в Windows для извлечения нужных строк из больших текстовых файлов является эффективным решением, особенно когда объем данных превышает 2 миллиона строк. С помощью findstr
, можно точно настраивать параметры поиска, включая обработку множества файлов с помощью шаблонов.