LinuxForum.Fans
Тема

grep или чем ещё можно выбрать все строки файла1 из файла2?

Автор: pljlm8463qmw 22 сообщений 2089 просмотров
09.08.2018 12:59 #429391

Задача

нужно выбрать из файла2 строки c email:fio из файла1

в файле2 строки с емэйлом и фио, а в файле1 только емэйлы
разделитель :


пример файлов

файл2 email:fio
vasya@mail.ru:Vasya
petya@list.ru:Petr Ivanov
sasha@bk.ru:Sasha S.


файл1 email
vasya@mail.ru
petya@list.ru
blabla@bla.ru

09.08.2018 13:05 #429392

Да чем угодно. На PHP или Python можно скрипт написать быстро. То есть, как я понял, в первом файле, без имён, может быть почта, которой нет во втором и это выбирать не надо? Правильно?

09.08.2018 13:30 #429393
Rizado написал:
Да чем угодно. На PHP или Python можно скрипт написать быстро. То есть, как я понял, в первом файле, без имён, может быть почта, которой нет во втором и это выбирать не надо? Правильно?

да

а можно без PHP или Python стандартными средствами unix grep sed awk или ещё как?)

09.08.2018 13:39 #429394
"pljlm8463qmw" написал:
а можно без PHP или Python стандартными средствами unix grep sed awk или ещё как?)

Тогда не ко мне вопрос.
Добавлено: 09.08.2018 1:39:53 pm

В общем, что Вам мешало сделать то же, что и я?
1. Набираем в консоли [console=inline]grep --help[/console].
2. Смотрим на опцию -f.
В итоге получилось:
[console]cat file2.txt | grep -f file1.txt[/console]
То, что надо?
При желании можно перенаправить вывод в файл:
[console]cat file2.txt | grep -f file1.txt > results.txt[/console]

P.S. Исправил опечатку.

09.08.2018 13:43 #429395

pljlm8463qmw, :) с grep нужно будет указывать где искать и что искать.
По сути это простой разгребатель хлама на диске.

09.08.2018 15:28 #429397
Rizado написал:
[quote="pljlm8463qmw"]а можно без PHP или Python стандартными средствами unix grep sed awk или ещё как?)

Тогда не ко мне вопрос.
Добавлено: 09.08.2018 1:39:53 pm

В общем, что Вам мешало сделать то же, что и я?
1. Набираем в консоли [console=inline]grep --help[/console].
2. Смотрим на опцию -f.
В итоге получилось:
[console]cat file2.txt | grep -f file1.txt[/console]
То, что надо?
При желании можно перенаправить вывод в файл:
[console]cat file2.txt | grep -f file1.txt > results.txt[/console]

P.S. Исправил опечатку.[/quote]

я так пробовал уже не находит из-за спецсимвола наверно в строке или хз из-за чего
grep -w -f file2.txt file1.txt>result.txt

вот сам попробуй

пример файла1

vasya@mail.ru:Vasya
petya@list.ru:Petr Ivanov
sasha@bk.ru:Sasha S.

пример файла2

vasya@mail.ru
blabla@bla.ru
petya@list.ru
blabla1@bla.ru
blabla2@bla.ru
blabla@3bla.ru
blabla4@bla.ru
sasha@bk.ru
blabla7@bla.ru

result.txt пустой получается (

09.08.2018 15:46 #429398
"pljlm8463qmw" написал:
вот сам попробуй

Для начала просьба повежливее. Я не давал согласия на "ты".

09.08.2018 15:53 #429399
Rizado написал:
[quote="pljlm8463qmw"]вот сам попробуй

Для начала просьба повежливее. Я не давал согласия на "ты".[/quote]

прошу прощения

09.08.2018 15:56 #429400

Я попробовал - всё работает:

text
$ grep -f file2 file1
vasya@mail.ru:Vasya
petya@list.ru:Petr Ivanov
sasha@bk.ru:Sasha S.
09.08.2018 16:12 #429401
Vascom написал:
Я попробовал - всё работает:
text
$ grep -f file2 file1
vasya@mail.ru:Vasya
petya@list.ru:Petr Ivanov
sasha@bk.ru:Sasha S.

я пробую на windows в cygwin

видимо он криво работает.... ничего не пойму

09.08.2018 16:17 #429402

pljlm8463qmw, я Вам написал готовый пример, который Вы подправили. Потому и не работает.
Комментирую по частям:
cat file2.txt - вывод содержимого файла в консоль.
| - вертикальная черта перенаправляет вывод, вместо экрана результат передаётся следующей команде.
grep -f file1.txt - искать строки, содержащиеся в файле (ключ -f) file1.txt
> results.txt - направить вывод в файл results.txt.
Всё вместе:
[console]cat file2.txt | grep -f file1.txt > results.txt[/console]
Так и вводите, одной командой и в одну строку. Только имена файлов свои подставьте.

09.08.2018 18:05 #429403
"pljlm8463qmw" написал:
видимо он криво работает.... ничего не пойму

Ну а если на оборот?:
[console]$ grep -f file1 file2[/console]

09.08.2018 18:14 #429404

на Kali linux попробовал тоже пустой вывод)))
какую кодировку надо у файла

"Vascom" написал:
grep -f file2 file1
"Rizado" написал:
pljlm8463qmw, я Вам написал готовый пример, который Вы подправили. Потому и не работает.
Комментирую по частям:
cat file2.txt - вывод содержимого файла в консоль.
| - вертикальная черта перенаправляет вывод, вместо экрана результат передаётся следующей команде.
grep -f file1.txt - искать строки, содержащиеся в файле (ключ -f) file1.txt
> results.txt - направить вывод в файл results.txt.

спасибо за развернутый ответ, я понимаю о чем речь
grep -f file2 file1 так тоже должно работать, но у меня не работает почему-то(((

пробовал на windows и cygwin и на Kalilinux и результат пустой!
всё работает если в файл1 только мыла без разделителя :
если в строке не только мыло а ещё другие символы то результат пустой

09.08.2018 18:16 #429405

Может проблемы из-за символов окончания строки?

09.08.2018 18:25 #429406
"ormorph" написал:
Ну а если на оборот?:

пробовал тоже пустой результат

инфа 100% он ищет точное совпадение походу строк и если кроме мыла другие символы в строке то пустой результат

не пойму как у Vascom работает
Добавлено: 09.08.2018 23:24:54

"Vascom" написал:
Может проблемы из-за символов окончания строки?

точно! спасибо

\r удалил в текстовом редакторе в файлах и всё получилось

а как бы это в одной команде сделать всё?) grep + sed ?

Добавлено: 09.08.2018 23:25:50

файлы очень большие >10ГБ

09.08.2018 19:09 · отредактировано #429407

Одной строчкой, то смотрите пример Rizado, просто добавить по середине еще один конвейер с командой sed 's/\r//' или tr -d "\r".
Добавлено: 09.08.2018 19:09:31

Глянул, grep может искать без учета CR, для этого есть ключик -u

09.08.2018 19:09 #429408
"ormorph" написал:
sed 's/\r//' или tr -d "\r".

экранирование с помощью "\" не помогло

sed 's%\r%%g' так работает

09.08.2018 19:14 #429409
"pljlm8463qmw" написал:
экранирование с помощью "\" не помогло

Не это не экранирование а удаление символов CR как вариант тогда sed 's/\r//g'
Ну и проще просто для grep добавить ключик -u, что бы искал без учета символов CR.

09.08.2018 19:38 #429410

"ormorph" написал:
Не это не экранирование а удаление символов CR как вариант тогда sed 's/\r//g'
так тоже работает спец символ \ в \r экранирует что sed 's/\r//g' что sed 's%\r%%' разницы нет

"ormorph" написал:
Ну и проще просто для grep добавить ключик -u, что бы искал без учета символов CR.
не пойму как это работает, не получается у меня правильно сделать :)
Добавлено: 10.08.2018 00:38:19

grep -u -f file2 file1 не работает)
09.08.2018 20:21 #429411
"pljlm8463qmw" написал:
файлы очень большие >10ГБ

Если это plain text, то у Вас вполне может быть несколько сотен миллионов записей. Здесь уже выгоднее на базу данных переходить, MySQL/MariaDB или SQLite.
Добавлено: 09.08.2018 8:21:06 pm

pljlm8463qmw, смотрите, в чём проблема. Давайте оценим вместе объём вычислений.

Вы пишете, что файлы больше 10 гигабайт, давайте примем по 10 дял удобства расчёта, даже 10^10 байт, а не 10 * 2^30.

Если адреса почты считать в среднем по 20 символов, а с именами по 40 (в реальности так и будет или даже немного меньше), то адресов почты у Вас будет 500 миллионов, а с именами вдвое меньше - 250 миллионов. И Вы хотите взять каждый из 500 миллионов адресов (по очереди!) и сверить их (тоже по очереди) с 250 миллионами строк. То есть, сравнений будет 500 * 10^6 * 250 * 10^6 = 125 * 10^15. Впечатляет? Плюс ресурсы системы на дисковые операции (если только у вас не 32 гигабайта ОЗУ, чтобы файлы там разместить), что тоже будет тормозить процесс. Если в несколько суток закончите - считайте, Вам повезло :) .

Подумайте над оптимизацией задачи или разбивкой её на части.

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