LinuxForum.Fans
Тема

Чем заменить долговыполняющийся grep -f

Автор: valet 4 сообщений 1293 просмотров
#279320

Появилась такая задача.
Имеется файл 1 такой:

данные1|имяфайла1|ещеданные1
данные2|имяфайла2|ещеданные2
...
данные100500|имяфайла100500|ещеданные100500

и файл 2 такой:

имяфайла1
имяфайла2
...
имяфайлаn

Задача: выбрать из файла 1 те строки с файлами и данными, которые есть в файле 2.
Ключ связи между ними - имяфайла.

Казалось бы это можно выполнить так:

text
grep -f 2 1 > result

Но это выполняется ну просто нереально долго, если в файле 2 много строк для отбора. Подозреваю, что можно как-то по-другому сделать. Может sed'ом как-то можно быстрее.

#279346

Наверное, с sed можно, но я очень редко им пользовался. Как я представляю, надо будет
вызывать его в цикле, чтобы он с каждым новым образцом удалял из первоначальной
копии файла1 найдённую строку и перезаписывал её, т.е. это будет плохо, если
перезаписываться будет на жёсткий диск, а не на виртуальный в оперативной памяти.
Вариант без sed - в скрипте по мере очередного прохождения файла1 составлять
двухсвязный список его номеров строк, из которого номера найдённых будут удаляться,
т.е. будут обходиться при поиске следующего образца. Если файлы неотсортированы,
то этот список сначала будет расти, а потом уменьшаться.

Пётр.

#279413
Lupo Alberto написал:
Гляньте man join.

Да, спасибо, это оно.
Как я только сам не догадался, что это эквивалентно этой задачи. Единственное нужно перенести поле <имяфайла> на первое место и отсортировать.
Еще раз:
Имеется файл f1 такой:

имяфайла1|данные1|ещеданные1
имяфайла2|данные2|ещеданные2
...
имяфайла100500|данные100500|ещеданные100500

и файл f2 такой:

имяфайла1
имяфайла2
...
имяфайлаn

Решение (может кому-то еще пригодится, пусть будет в одном месте):

sort f1 -o f1
sort f2 -o f2
join -t"|" f1 f2 2> /dev/null > result

Вопрос решен!
Тему можно перенести в решенные.

Войдите или зарегистрируйтесь, чтобы ответить.