Как запретить grep печатать одну и ту же строку несколько раз?


15

Если я grep файл, содержащий следующее:

These are words
These are words
These are words
These are words

... для слова These, он напечатает строку These are wordsчетыре раза.

Как я могу запретить grep печатать повторяющиеся строки более одного раза? В противном случае, как я могу манипулировать выводом grep для удаления повторяющихся строк?


Должен ли порядок совпадений быть сохранен в выходных данных? В противном случае отправленная команда John1024 будет работать.
Кос

Ответы:


23

Философия Unix состоит в том, чтобы иметь инструменты, которые делают одно и делают их хорошо. В данном случае grepэто инструмент, который выделяет текст из файла. Чтобы узнать, есть ли дубликаты, нужно отсортировать текст. Чтобы удалить дубликаты, используется -uопция sort. Таким образом:

grep These filename | sort -u

sortЕсть много вариантов: см man sort. Если вы хотите сосчитать дубликаты или использовать более сложную схему для определения того, что является или не является дубликатом, направьте выходные данные сортировки по адресу uniq: grep These filename | sort | uniqи посмотрите параметры в manuniq`.


2

Использование grepи дополнительного переключателя, если вы ищете только одну строку

grep -m1 'These' filename

Из man grep

-m NUM, --max-count=NUM
        Stop reading a file after NUM matching lines.  If the input is
        standard input from a regular file, and NUM matching lines are
        output, grep ensures that the standard input is positioned  to
        just  after  the  last matching  line  before exiting, regardless
        of the presence of trailing context lines.  This enables a calling
        process to resume a search.  When grep stops after NUM matching
        lines, it outputs any trailing context lines.  When the -c or
        --count option is also used, grep does not output a count greater
        than NUM.  When the -v or --invert-match option is also used, grep
        stops after outputting NUM non-matching lines.

или используя awk ;)

awk '/These/ {print; exit}' foo

ИМХО, наиболее подходящий ответ - флаг -m. Я предлагаю вам поставить его в верхней части вашего ответа. Очень хороший ответ!
Сергей Колодяжный

3
Это не сработает, если вы используете регулярное выражение - оно остановится сразу после первого совпадения, а не убедитесь, что вы получаете один и только один из каждого возможного совпадения.
csvan
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.