2

Я использую Windows 7 64 бит

У меня есть большой файл .txt (800 МБ плюс), содержащий следующий формат

файл разделен пробелом

8232394 06774483 N 19850910 19870818 19910818 EXP. 
8309716 06774483 N 19850910 19870818 19910319 REM.
4687262 06908244 N 19860917 19870818 19990815 EXP. 
4687262 06908244 N 19860917 19870818 19990309 REM. 
4687262 06908244 N 19860917 19870818 19950221 M184 
4687262 06908244 N 19860917 19870818 19910108 M173 
4687262 06908244 N 19860917 19870818 19880802 ASPN 
4687263 06868897 N 19860527 19870818 19990128 M185
4687263 06868897 N 19860527 19870818 19950509 RMPN
4687263 06868897 N 19860527 19870818 19950509 ASPN 
4687263 06868897 N 19860527 19870818 19950119 M184 
4687263 06868897 N 19860527 19870818 19910311 ASPN 
4687263 06868897 N 19860527 19870818 19910124 M173 
4687264 06882047 N 19860703 19870818 19990815 EXP. 
4687264 06882047 N 19860703 19870818 19990309 REM. 
4687264 06882047 N 19860703 19870818 19950503 RMPN 
4687264 06882047 N 19860703 19870818 19950503 ASPN 
4687264 06882047 N 19860703 19870818 19950119 M184 
4687264 06882047 N 19860703 19870818 19910311 ASPN 
RE45781 14176526 N 20140210 20151027 20150929 ASPN 
RE45786 14260890 N 20140424 20151027 20150929 ASPN 
RE45790 14454285 Y 20140807 20151103 20151008 ASPN 
RE45793 13445791 N 20120412 20151103 20151006 ASPN 

У меня есть другой файл .txt (маленький), содержащий следующий формат

4687264 
4687264 
4687264 
RE45781 
RE45786 
RE45790 
RE45793 

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

Файл результатов должен выглядеть следующим образом

4687264 06882047 N 19860703 19870818 19990815 EXP. 
4687264 06882047 N 19860703 19870818 19990309 REM. 
4687264 06882047 N 19860703 19870818 19950503 RMPN 
4687264 06882047 N 19860703 19870818 19950503 ASPN 
4687264 06882047 N 19860703 19870818 19950119 M184 
4687264 06882047 N 19860703 19870818 19910311 ASPN 
RE45781 14176526 N 20140210 20151027 20150929 ASPN 
RE45786 14260890 N 20140424 20151027 20150929 ASPN 
RE45790 14454285 Y 20140807 20151103 20151008 ASPN 
RE45793 13445791 N 20120412 20151103 20151006 ASPN 

Там в любом случае?

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

ВИМ ФОРУМ

2 ответа2

2

GREP

Используя GNU grep вы можете сделать

$ grep -f small_list.txt big_file.txt
4687264 06882047 N 19860703 19870818 19990815 EXP.
4687264 06882047 N 19860703 19870818 19990309 REM.
4687264 06882047 N 19860703 19870818 19950503 RMPN
4687264 06882047 N 19860703 19870818 19950503 ASPN
4687264 06882047 N 19860703 19870818 19950119 M184
4687264 06882047 N 19860703 19870818 19910311 ASPN
RE45781 14176526 N 20140210 20151027 20150929 ASPN
RE45786 14260890 N 20140424 20151027 20150929 ASPN
RE45790 14454285 Y 20140807 20151103 20151008 ASPN
RE45793 13445791 N 20120412 20151103 20151006 ASPN

(проверено на Linux после вырезания и вставки ваших точных данных)

Если вы хотите и можете установить и использовать vim, у grep не должно быть проблем.

FINDSTR

Вы также можете сделать это с помощью родного findstr

C:> findstr /G:small_list.txt big_file.txt
4687264 06882047 N 19860703 19870818 19990815 EXP.
4687264 06882047 N 19860703 19870818 19990309 REM.
4687264 06882047 N 19860703 19870818 19950503 RMPN
4687264 06882047 N 19860703 19870818 19950503 ASPN
4687264 06882047 N 19860703 19870818 19950119 M184
4687264 06882047 N 19860703 19870818 19910311 ASPN
RE45781 14176526 N 20140210 20151027 20150929 ASPN
RE45786 14260890 N 20140424 20151027 20150929 ASPN
RE45790 14454285 Y 20140807 20151103 20151008 ASPN
RE45793 13445791 N 20120412 20151103 20151006 ASPN

Я только упомянул grep сначала по привычке и потому что я часто забываю, что findstr не так уж и глуп, как я думал раньше.

Предостережение

Я уверен, что у grep не будет проблем с очень большими файлами. Я менее уверен в Findstr, но я не могу придумать причину, чтобы не попробовать это.


Приложение:

Регулярные выражения

И grep и findstr могут находить фиксированные строки, но они также могут работать с регулярными выражениями.

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

^4687264 
^RE45781 
^RE45786 
^RE45790 
^RE45793 

Вы можете сделать это в vim используя :%s/^/^/ - вы также можете использовать sed, awk, perl и т.д. Для редактирования файла строки поиска так же легко. Обратите внимание, что первый ^ в части поискового выражения команды s (замещать) является метасимволом, означающим "начало строки". Второй ^ находится в части строки замены, где он означает буквальный символ ^ .

Если бы я не хотел редактировать файл найденных строк, я бы сделал что-то вроде

sed -e 's/^/^/' < small_list.txt > temp.txt; grep -f temp.txt big_file.txt; rm temp.txt

grep предполагает регулярные выражения. С помощью findstr вам нужно добавить параметр /R в команду (не проверено).

0

Powershell

понятия не имею о производительности во время выполнения, но powershell установлен по умолчанию во всех текущих операционных системах Windows

$small = (gc small.txt | group).Name
gc large.txt | ? {$small -contains $_.Split(" ")[0]}

Сломать

$small = (gc small.txt | group).Name
 - Get-Content of small.txt
 - Group the content to retain a list of unique values as to speed up the search
 - Store in $small variable

gc large.txt | ? {$small -contains $_.Split(" ")[0]}
 - Get-Content of large.txt
 - ? => where clause
   - $_ contains a complete line from large.txt. 
     Split it up by spaces and just select the first element of that result
   - Search the first element in the $small list

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .