Команда Unix для поиска пересечений или выбросов набора строк?
Вопрос
Существует ли команда UNIX наравне с
sort | uniq
чтобы найти пересечения набора строк или "выбросы".
Пример приложения:У меня есть список html-шаблонов, некоторые из них содержат строку {% load i18n %} внутри, другие - нет.Я хочу знать, какие файлы этого не делают.
Редактировать: grep -L решает вышеуказанную проблему.
Как насчет этого:
файл1:
mom
dad
bob
файл2:
dad
%пересекать файл1 file2
dad
%осталось-уникальный файл1 file2
mom
bob
Решение
Похоже , что grep -L
решает реальную проблему плаката, но для собственно заданного вопроса о нахождении пересечения двух наборов строк вы, возможно, захотите заглянуть в команду "comm".Например, если file1
и file2
каждый содержит отсортированный список слов, по одному слову в строке, затем
$ comm -12 file1 file2
будут выведены слова, общие для обоих файлов.В более общем плане, учитывая отсортированные входные файлы file1
и file2
, команда
$ comm file1 file2
выдает три столбца выходных данных
- строки только в file1
- строки только в file2
- строки как в file1, так и в file2
Вы можете подавить столбец N
в выходных данных с -N
вариант.Итак, приведенная выше команда, comm -12 file1 file2
, подавляет столбцы 1 и 2, оставляя только слова, общие для обоих файлов.
Другие советы
Пересекать:
# sort file1 file2 | uniq -d
dad
Оставленный уникальным:
# sort file1 file2 | uniq -u
bob
mom
Возможно, я неправильно понимаю вопрос, но почему бы просто не использовать grep для поиска строки (используйте опцию -L, чтобы заставить ее печатать имена файлов, в которых нет строки).
Другими словами
grep -L "{% load i18n %}" file1 file2 file3 ... etc
или с соответствующими подстановочными знаками для имен файлов.
От http://www.commandlinefu.com/commands/view/5710/intersection-between-two-files:
Пересечение между двумя (несортированными) файлами:
grep -Fx -f file1 file2
Строки в file2, которых нет в file1:
grep -Fxv -f file1 file2
Объяснение:
- В
-f
опция сообщает grep прочитать шаблоны для поиска из файла.Это означает, что он выполняет поиск file2 для каждой строки в file1. - В
-F
опция указывает grep видеть условия поиска как фиксированные строки, а не как шаблоны, так чтоa.c
будет соответствовать толькоa.c
и неabc
, - В
-x
опция указывает grep выполнять поиск по всей строке, чтобы "foo" в file1 не совпадало с "foobar" в file2. - По умолчанию grep будет показывать только совпадающие линии, указывая вам пересечение.В
-v
опция указывает grep показывать только несоответствующий строки, дающие вам строки, уникальные для file2.
от человека grep
-L, --files-without-match
Подавлять нормальный выходной сигнал;вместо этого выведите имя каждого входного файла, из которого обычно выходные данные не были бы напечатаны .Сканирование прекратится на первом совпадении.
Итак, если ваши шаблоны представляют собой HTML-файлы, которые вы хотите:
grep -L '{% load i18n %}' *.html
Пересечение:
comm -12 <(cat file1 | sort | uniq) <(cat file2 | sort | uniq)
Все строки по 3 столбцам (файл1 | файл2 | пересечение):
comm <(cat file1 | sort | uniq) <(cat file2 | sort | uniq)
Если ваши файлы не отсортированы и / или если внутри одного из файлов могут быть строки, которые дублируются, но не отображаются в другом - эта однострочная команда отсортирует ваши файлы, удалит дублированные строки, и вы сразу получите желаемый результат.