grep: сравнение списка из одного или нескольких слов в каждой строке с текстовым файлом - PullRequest
0 голосов
/ 14 января 2011

Я работаю на ОС Debian / GNU Linux и мне нравится использовать короткую команду оболочки (терминал или скрипт extern).

Моя цель: у меня есть список слов в foo.txt, например

---- foo.txt ----

dog
cat
mouse with hat

---- /foo.txt ----

и хотите сравнить этот список с bar.txt (подразумевается обычный текст с некоторыми абзацами).

Я бы хотел провести два матча:

  1. все слова в каждой строке должны совпадать (например, «мышь с шляпой» и просто «шляпа»)

  2. только первое совпадение каждой строки должно совпадать

Относится к первой проблеме:

Мой первый код (пока что для командной строки) и мои проблемы:

for i in foo.txt; do fgrep -f foo.txt bar.txt

просто соответствует первому слову в списке. Теперь я думаю, что я должен использовать что-то вроде

for i in foo.txt; do fgrep -e <some-kind-of-regexp> -f foo.txt bar.txt

но я увяз с регулярным выражением: (

Относится ко второй проблеме Для остановки grep я знаю только опцию -m.

for i in foo.txt; do fgrep -m 1 -f foo.txt bar.txt

останавливается после первого с любыми совпадениями. Но мне нравится что-то вроде «искать любое первое совпадение и останавливаться после просмотра всего списка».

1 Ответ

1 голос
/ 23 февраля 2011

На ваш первый вопрос, вам нужно разделить список на отдельные слова, прежде чем передать его в grep.Я использую awk для этого, но вы также можете использовать sed.Я делю на пробелы, но вы могли бы также легко разделить на не алфавитно-цифровые, если это то, что вы хотели:

fgrep -f <(mawk 'BEGIN{FS=" "}{print; if(NF > 1)for(i=1; i<=NF; i++)print $i}' foo.txt) bar.txt

На ваш второй вопрос, вам нужно немного подуматьСначала выведите номер строки вместе с каждой совпадающей строкой, затем вы можете уникальным образом сопоставить строку, чтобы получить номер строки, соответствующий каждой строке.

cat bar.txt \
| mawk '{print NR,$0}' \
| join -1 1 -2 1 - <(fgrep -o -n -f <(mawk 'BEGIN{FS=" "}{print; if(NF > 1)for(i=1; i<=NF; i++)print $i}' foo.txt) bar.txt \
| sort -k2,2 -k1,1n \
| sort -k2,2 -us \
| cut -f1 \
| sort -k1,1)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...