grep reverse с точным соответствием - PullRequest
1 голос
/ 08 января 2020

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

Файл списка

nw_66 17296
nw_67 21414
nw_68 21372
nw_69 27387
nw_70 15830
nw_71 32348
nw_72 21925
nw_73 20363

master файл

nw_1 5896
nw_2 52814
nw_3 14537
nw_4 87323
nw_5 56466
......
......
nw_n xxxxx

пока пытаюсь, но не работает должным образом.

for i in $(awk '{print $1}' list.txt); do grep -v -w $i master.txt; done;

Пожалуйста, помогите

Ответы [ 3 ]

1 голос
/ 08 января 2020

Дайте этому awk однострочнику попробовать:

awk 'NR==FNR{a[$1]=1;next}!a[$1]' list master
0 голосов
/ 08 января 2020

ОП попытался выполнить следующую строку:

for i in $(awk '{print $1}' list.txt); do grep -v -w $i master.txt; done;

Эта строка не будет работать, так как для каждой записи $i, вы печатаете все записи в master.txt tat не эквивалентны до "$i". Как следствие, вы получите несколько копий master.txt, в каждой из которых будет отсутствовать одна строка.

Пример:

$ for i in 1 2; do grep -v -w "$i" <(seq 1 3); done
2     \ copy of seq 1 3 without entry 1
3     /
1     \ copy of seq 1 3 without entry 2
3     /

Кроме того, попытка прочитать файл master.txt несколько раз. Это очень неэффективно.

Инструмент unix grep позволяет проверить несколько выражений, хранящихся в файле в одном go. Это делается с помощью флага -f. Обычно это выглядит следующим образом:

$ grep -f list.txt master.txt

ОП теперь может использовать это следующим образом:

$ grep -vwf <(awk '{print $1}' list.txt) master.txt

Но это будет соответствовать по всей строке.

Решение awk , представленное Kent , является более гибким и позволяет OP определять более настроенное соответствие:

awk 'NR==FNR{a[$1]=1;next}!a[$1]' list master

Здесь OP ясно заявляет, что я хочу сопоставить столбец 1 списка с столбец 1 мастера, и меня не волнуют пробелы или что-либо еще в столбце 2. Решение grep может по-прежнему соответствовать записям в столбце 2.

0 голосов
/ 08 января 2020

Может быть, это поможет:

awk 'NR == FNR {id[$1]=1;next}
{
    if (id[$1] == "") {
        print $0
    }
}' listfile masterfile

Мы принимаем 2 файла в качестве входных данных, первый - listfile, второй - masterfile.

NR == FNR будет правдой, пока awk проходит через listfile. В ассоциативном массиве id[] все идентификаторы в listfile сделаны ключом со значением как 1.

Когда awk проходит через masterfile, он печатает только строку, если $1 т.е. идентификатор не является ключом в массиве ids.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...