Удалить строку, если она содержит точную строку из строки другого файла - PullRequest
0 голосов
/ 30 мая 2019

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

Вот файл:

one@email.com,name,surname,city,state
two@email.com,name,surname,city,state
three@email.com,name,surname,city,state
anotherone@email.com,name,surname,city,state

А вот список примеровдля фильтрации:

one@email.com
three@email.com

Требуемый вывод:

two@email.com,name,surname,city,state
anotherone@email.com,name,surname,city,state

Я попытался сделать это, используя следующее:

grep -v -f 2.txt 1.txt > 3.txt

Однако это приводит квывод:

two@email.com,name,surname,city,state

Я предполагаю, что это происходит потому, что "anotherone@email.com" содержит "one@email.com".Я искал способ включить начало строки, но не нашел ничего подходящего.

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

Ответы [ 3 ]

2 голосов
/ 30 мая 2019

Предполагая, что ваш входной файл содержит three@gmail.com, а не three@email.com (возможно, опечатка)

$ grep -vw -f 2.txt 1.txt
two@email.com,name,surname,city,state
anotherone@email.com,name,surname,city,state

-w, --word-regexp - Выражение ищется как слово (как если бы оно было окружено [[:<:]]' and [[:>:]] ';

0 голосов
/ 30 мая 2019

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

awk -F, -v OFS=, '
    BEGIN   { split("", m) }
    NR==FNR { m[$0] = ""; next }
    !($1 in m)
' filter.txt file.txt

Но ... если мы хотим отфильтровать любое вхождениестрока в любом месте строки (точное ограничение без ограничений) нам нужно сделать что-то менее умное и более грубое:

awk '
    BEGIN {
        split("", m)
        n=0
    }
    NR==FNR {
        m[n++] = $0
        next
    }
    {
        for (i=0; i<n; ++i) {
            if (index($0, m[i]))
                next
        }
        print
    }
' filter.txt file.txt

Обратите внимание, что если фильтр содержит непечатные символы (например, не-unix-окончания строк)), нам нужно разобраться с ними, отфильтровав их (например, с помощью sub(/\r/, "")).

0 голосов
/ 30 мая 2019

Если вам нравится печатать только строки из первого файла, который does not содержит данные из второго файла в первом поле, то это должно сделать:

$cat file
one@email.com,name,surname,city,state
two@email.com,name,surname,city,state
three@email.com,name,surname,city,state
anotherone@email.com,name,surname,city,state
$cat filter
one@email.com
three@email.com

awk -F, 'NR==FNR {a[$0]++;next} !($1 in a)' filter file
two@email.com,name,surname,city,state
anotherone@email.com,name,surname,city,state

Для каждой строки в filter создается массив a с именем и значением 1
Как a[one@email.com]=1 и a[three@email.com]=1
Затем awk тестирует строку за строкой в ​​file против массива, давая

a[one@email.com]=1
a[two@email.com]=
a[three@email.com]=1
a[anotherone@email.com]=

Затем выведите всю строку из file без 1

two@email.com,name,surname,city,state
anotherone@email.com,name,surname,city,state
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...