1

У меня есть 2 больших текстовых файла (~ 500M, ~ 15GB ea), которые выглядят так:

FileP.txt:

test@test.com:testtest 
test@test.com1:testtest1
test@test.com2:testtest2
test@test.com3:testtest3
test@test.com4:testtest4

FileE.txt

test@test.com:testtest
test@test.com0:testtest0
test@test.com2:testtest2
test@test.com3:testtest3
test@test.com5:testtest5

(Обратите внимание, что в FileE.txt есть строки, которых нет в FileP.txt . Я не хочу, чтобы те включены. Жирные линии - это строки, которые должны заканчиваться в output.txt , поскольку их нет в FileE.txt .)

Я хочу запустить FileE.txt против FileP.txt и удалить все строки, которые были найдены в FileE.txt из FileP.txt и вывести их в новый файл.

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

output.txt:

test@test.com1:testtest1
test@test.com4:testtest4

Я попробовал несколько команд,

Вот моя команда grep:

$ grep -Fvxf FileE.txt FileP.txt > output.txt

Тем не менее, я получаю эту ошибку (очевидно, потому что файлы слишком велики):

grep: memory exhausted

Для тех, кто заинтересован, запуск $ ulimit -a возвращает:

core file size          (blocks, -c) unlimited
data seg size           (kbytes, -d) unlimited
file size               (blocks, -f) unlimited
open files                      (-n) 256
pipe size            (512 bytes, -p) 8
stack size              (kbytes, -s) 2032
cpu time               (seconds, -t) unlimited
max user processes              (-u) 256
virtual memory          (kbytes, -v) unlimited

Итак, мой вопрос, что было бы наиболее эффективным и простым способом завершить этот процесс?

ПРИМЕЧАНИЕ. Файлы не отсортированы.

2 ответа2

0

Если файлы отсортированы, сделайте

comm -23 fileP.txt fileE.txt

comm сравнивает два отсортированных файла и ищет общие для них строки.  Например, учитывая этот файл цветов, имена которых начинаются с согласных:

blue
green
purple
red
white
yellow

и этот список цветов, имена которых заканчиваются на гласные:

blue
indigo
orange
purple
white

команда comm colors1 colors2 производит этот вывод:

                blue
green
        indigo
        orange
                purple
red
                white
yellow

где:
первый столбец содержит цвета, которые начинаются и заканчиваются согласными (в colors1 но не colors2), второй столбец содержит цвета, начинающиеся и заканчивающиеся гласными (в colors2 но не colors1), а третий столбец содержит цвета, которые начинаются с согласных и заканчиваются с гласными (как в colors1 и в colors2).  Для ваших файлов (показанных в вашем вопросе), comm fileP.txt fileE.txt производит

                test@test.com:testtest
        test@test.com0:testtest0
test@test.com1:testtest1
                test@test.com2:testtest2
                test@test.com3:testtest3
test@test.com4:testtest4
        test@test.com5:testtest5

Параметры немного не интуитивны: -23 означает подавление второго и третьего столбцов, показывая только первый (строки, которые находятся в первом файле, но не во втором).  Так,

$ comm -23 fileP.txt fileE.txt
test@test.com1:testtest1
test@test.com4:testtest4

Обратите внимание, что это не будет работать правильно, если файлы не отсортированы.  Если файлы не отсортированы, сортируйте их.

0

Чтобы увеличить комментарий по xenoid, отсортируйте файлы и введите

diff fileP.txt fileE.txt | sed -n 's/^< //p'

Выходные данные diff показывают строки, которые находятся только в первом файле, с предшествующим , и строки, которые находятся только во втором файле, с предшествующим sed выбирает только те строки, которые начинаются с и удаляет их.

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