Linux подсчет одинаковых строк

COREUTILS. Команда uniq. Вывод уникального содержимого

Общий синтаксис программы uniq в linux предельно простой:

unic [OPTIONS] [INPUT [OUTPUT]]

Тоесть, чтобы вывести уникальные строки, например в тестовом файле my_text_file, нужно команде uniq передать его имя в качестве аргумента

Нельзя, разумеется, забывать, что вы должны находится именно в той дирректории, где и лежит файл my_text_file. Иначе uniq необходимо передать полный путь до файла в linux:

Неуникальные строки можно посчитать. Для этого передайте quic в качестве опции ключ «-c».

unic -c /home/user/my_text_file

В выводе вы получите таблицу из 2-х колонок, в первой будет указано количество повторяющихся строк, во второй их значение.

В linux uniq также можно попросить печатать только те строки, которые имеют дубликаты, для этого нужно использовать ключ «-d»:

uniq -d /home/user/my_text_file

Опции можно комбинировать, и чтобы посчитать только строки которые имеют дубликаты, следует ввести такую команду:

uniq -d -с /home/user/my_text_file

В противовес ключу «-d» есть ключ «-u», заставляющий uniq выводить только строки, не имеющие дубликата:

uniq -u /home/user/my_text_file

Однако, как мы и освещали в вводой части, uniq работает только последовательно, следовательно строки, содержащиеся в файле, например:

не будут считаться уникальными. Чтобы разрешить эту проблему можно использовать в linux команду uniq совместно с командой sort, перенаправляя вывод одной команды на ввод другой:

sort -n my_text_file | uniq

или же просто использовать sort с ключом «-u»

sort -n -u my_text_file

Возможности и примеры использования утилиты sort мы уже освещали в статье COREUTILS. Команда sort. Сортировка вывода программ

Источник

Узнать количество строк в файле Linux

Довольно частенько нужно подсчитать количество файлов при выводе в консоли BASH. Хорошо если файлов 10 единиц. Как быть если их сотни и у каждого файла сложное имя. Тут идеально подойдёт команда wc. Её наилучше использовать вместе с фильтром. Например с командой grep команда wc хорошо сочетается. Возможно подсчитать количество слов в документе.

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

Подсчет строк, слов и знаков с помощью wc

Система отвечает строкой в следующем формате: l w c файл

где l — число строчек в файле;
w — число слов в файле;
c — число символов в файле.

Чтобы подсчитать количество строк, слов и символов в нескольких файлах, используйте следующий формат:

Система говорит следующим образом:

l w c файл1
l w c файл2
l w c total

Число строк, слов и символов для файл1 и файл2 отражается на отдельных строках. На последней строке отображается общее число строк, слов и знаков в двух файлах.

Подсчет данных в документе

wc text.txt
вывод: 40 149 947 text.txt

В первоначальной колонке содержится количество строк, во второй кол-во слов, в третьей кол-во знаков

wc -l file.txt #вывести количество строк (ряд знаков, написанных или напечатанных в одну линию)
wc -c file.txt #вывести количество байт
wc -m file.txt #вывести число символов
wc -L file.txt #вывести длину самой длинной строки
wc -w file.txt #вывести число слов

Подсчёт данных в выводе командной строки Linux

ls -al | grep ‘.txt’ | wc -l

ls -al | grep ‘.txt’ | wc -w

Подсчет количества .txt-файлов в текущем каталоге с помощью wc:

При выводе в инструктивной строке очень часто попадают файлы с точками вместо имён .. или . .Тут необходимо отфильтровать вывод и только потом применять команду wc. Как подсчитать количество файлов в папки. Тут добавлена сортировка и удаление дублей. uniq — убирает дубли, перед unic обязана идти сортировка sort

Поиск количества файлов в директории Linux

ls | grep «name» | sort | uniq | wc -l

Подсчет уникальных строк и дубликатов в текстовом файле Linux

Буквально сегодня на работе столкнулся с довольно простой задачей, состоящей из двух подзадач: 1) нужно было подсчитать в текстовом файле количество уникальных строк 2) подсчитать в уже другом файле количество строчек, которые дублируются.

С этими задачами я справился и после этого подумал — по какой причине бы не написать небольшой пост, вдруг кому-нибудь пригодится. Подсчитаем в нём количество уникальных строчек с помощью следующей команды:

$ sort data.txt | uniq -u | wc -l

Всё достаточно просто. Утилита uniq с функцией -u выводит на экран уникальные строки (u—unique, видимо так) и с помощью | результат перенаправляется в утилиту wc , какая просто считает количество строк, т.к. исполняется с опцией -l. В самом начале нам необходимо просортировать входной поток данных (текстовый файл), иначе утилита uniq не сможет правильно подсчитать уникальные строки. Выполняется сортировка с помощью sort и результат, используя |, перенаправляется в uniq. После исполнения такой команды для файла data.txt на экран будет выведено число 5.

Для этого чтобы решить вторую подзадачу, сделаем всё тоже самое, только uniq станет выполнен с опцией -d (видимо d—duplicate):

$ sort data.txt | uniq -d | wc -l

Читайте также:  Windows 10 сырая или нет

В результате на экран выведено количество 2. Обе подзадачи решены достаточно простым способом. Записал небольшую демонстрацию кому забавно.

Подсчитать количество строк в файле Linux

Нет ничего проще, чем подсчитать количество строчек в файле.

cat filename.txt | wc -l

Подсчитать общее количество строк в файлах (именованная область данных на носителе информации) по шаблону. Если же вам необходимо подсчитать количество строк нескольких файлов, можете использовать шаблон, например:

Источник

Команда uniq Linux

Команда uniq предназначена для поиска одинаковых строк в массивах текста. При этом с найденными совпадениями пользователь может совершать множество действий — например, удалять их из вывода либо наоборот, выводить только их.

Работа команды осуществляется как с текстовыми файлами (в том числе, записями скриптов), так и с текстом, напечатанным в командной строке терминала.

Синтаксис uniq

Запись команды осуществляется следующим образом:

$ uniq опции файл_источник файл_для_записи

Файл источник указывает откуда надо читать данные, а файл для записи — куда писать результат. Но их указывать не обязательно. В примерах мы будем набирать текст, который нуждается в редактировании, прямо в командную строку терминала, воспользовавшись ещё одной командой — echo, и применив к ней опцию -e. Это будет выглядеть так:

echo -e [текст, слова в котором разделены управляющей последовательностью\\n] | uniq

Эта управляющая последовательность нужна, чтобы указать утилите, что каждое слово выводится в новой строке. Если указано только название файла источника, результат выполнения команды появится прямо в окне терминала. А при наличии выходного файла текст будет напечатан в теле документа.

Опции uniq

У команды uniq есть такие основные опции:

  • -u (—unique) — выводит исключительно те строки, у которых нет повторов.
  • -d (—repeated) — если какая-либо строка повторяется несколько раз, она будет выведена лишь единожды.
  • -D — выводит только повторяющиеся строки.
  • —all-repeated[=МЕТОД] — то же самое, что и -D, но при использовании этой опции между группами из одинаковых строк при выводе будет отображаться пустая строка. [=МЕТОД] может иметь одно из трех значений — none (применяется по умолчанию), separate или prepend.
  • —group[=МЕТОД] — выводит весь текст, при этом разделяя группы строк пустой строкой. [=МЕТОД] имеет значения separate (по умолчанию), prepend, append и both, среди которых нужно выбрать одно.

Вместе с основными опциями могут применяться дополнительные. Они нужны для более тонких настроек работы команды:

  • -f (—skip-fields=N) — будет проведено сравнение полей, начиная с номера, который следует после указанного вместо буквы N. Поля — это слова, хотя, называть их словами в прямом смысле слова нельзя, ведь словом команда считает любую последовательность символов, отделенную от других последовательностей пробелом либо табуляцией.
  • -i (—ignore-case) — при сравнении не будет иметь значение регистр, в котором напечатаны символы (строчные и заглавные буквы).
  • -s (—skip-chars=N) — работает по аналогии с -f, однако, игнорирует определенное количество символов, а не строк.
  • -c (—count) — в начале каждой строки выводит число, которое обозначает количество повторов.
  • -z (—zero-terminated) — вместо символа новой строки при выводе будет использован разделитель строк NULL.
  • -w (—check-chars=N) — указание на то, что нужно сравнивать только первые N символов в строках.

Примеры использования uniq

Прежде всего следует отметить главную особенность команды uniq — она сравнивает только строки, которые находятся рядом. То есть, если две строки, состоящие из одинакового набора символов, идут подряд, то они будут обнаружены, а если между ними расположена строка с отличающимся набором символов — то не будут поэтому перед сравнением желательно отсортировать строки с помощью sort. Без задействования файлов uniq работает так:

echo -e небо\\nоблака\\nоблака\\nоблака\\nсолнце\\nзвезды | uniq

После команды uniq можно использовать её опции. Вот пример вывода, где не просто удалены повторы, но и указано количество одинаковых строк:

echo -e небо\\nоблака\\nоблака\\nоблака\\nсолнце\\nзвезды | uniq -c

Теперь применим команду к тексту, который находится в файле.

uniq —all-repeated=prepend text-example.txt

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

Причина этого — незаметный глазу символ пробела, который стоит в конце одной из строк первой группы. Нужно быть предельно внимательным при использовании uniq, чтобы получить качественный результат.

Используемая опция —all-repeated=prepend выполнила свою работу — добавила пустые строки в начало, в конец и между группами строк. Теперь попробуем сравнить только первые 5 символов в каждой строке.

echo -e небо исполосовано молниями\\nоблака на небе\\nоблака разогнал ветер\\nоблака закрыли солнце\\nсолнце светит ярко\\nзвезды кажутся огромными | uniq -w5

Как видно на скриншоте, повторяющиеся строки, которые начинались словом «облака», были удалены. Осталась только первая из них. Вывод только уникальных строк с использованием опции -u выглядит так:

echo -e небо\\nоблака\\nоблака\\nоблака\\nсолнце\\nзвезды | uniq -u

Чтобы проигнорировать определенное количество символов в начале одинаковых строк, воспользуемся опцией —skip-chars. В данном случае команда пропустит слово «облака», сравнив слова «перистые» и «белые».

echo -e небо\\nоблака перистые\\nоблака перистые\\nоблака белые\\nсолнце\\nзвезды | uniq —skip-chars=6

А вот наглядная демонстрация отличий при использовании опции —group с разными значениями. both добавило пустые строки как перед текстом, так и после него, а также между группами строк.

echo -e небо\\nоблака\\nоблака\\nоблака\\nсолнце\\nзвезды | uniq —group=both

Тогда как append не добавило пустую строку перед текстом:

echo -e небо\\nоблака\\nоблака\\nоблака\\nсолнце\\nзвезды | uniq —group=append

Выводы

Команда uniq linux пригодится тем, кто часто и много работает с массивами текста, не имея возможности вычитывать их самостоятельно. Следует заметить, что не все версии uniq работают исправно, поэтому иногда результат выдачи может отличаться от ожидаемого.

Свои вопросы относительно использования команды, а также замечания и пожелания оставляйте в комментариях.

Источник

[Bash] Поиск строк с общими полями и подсчет количества совпадений

Доброго времени суток!

Читайте также:  Windows 10 ноутбук не меняется яркость

Нуждаюсь в помощи опытных коллег.

Есть файл такого содержания

  • Иван:Петров
  • Сергей:Петров
  • Виктор:Петров
  • Вадим:Петров
  • Алексей:Петров
  • Станислав:Сидоров
  • Вячеслав:Сидоров
  • Геннадий:Сидоров
  • Владимир:Сидоров
  • Арсений:Сидоров
  • Константин:Иванов
  • Дмитрий:Иванов
  • Игорь:Иванов

Мне нужно подсчитать кол-во совпадений второго поля и найти строки в которых кол-во совпадений n меньше заданного N в скрипте (в данном случае 5) и использовать второе поле из этих строк в качестве переменной $var_surname для дальнейших действий.

на выходе нужно получить

Буду благодарен любым подсказкам.

1. идешь while-ом по строке 2. пишешь функцию, подсчета совпадений 3. на каждой итерации, бери фамилию. разделитель двоеточие передавай в функцию поиска из пункта 2 (awk -F ‘:’ ‘‘) 3. функция поиска делает поиск (cat input | grep -i -c surname) и делает append в массив, хеш-мап нет, поэтому добавляй, в одну строку, потом при сортировке распарсишь, вида: surname:count 4. пишешь функцию сортировку 5. после идешь for-ом по массиву surname:count, передаешь на каждой итерации строку в функцию сортировки 6. в функции сортировки: сплит по ‘:’, и сравниваешь count по условию, если удовлетворяет, принтуешь или что тебе там нужно.

Вырезаешь второе поле man cut или man grep . Сортируешь man sort . Считаешь каждое входение man uniq . Получаешь список «кол-во фамилия». Дальше сам

Как говорит тут один аноним, сразу видно пятизвёздочного. Ну накой awk -F ‘:’ ‘‘ если уже есть while? Это делается while IFS=: read name surname; С чего это нету map-а? Тут явно напрашивается ассоциативный массив. Ну и так далее.

Спасибо, очень помог) Простое и доступное для меня решение.

cat unionfile | cut -d»:» -f2 | sort | uniq -c > output

sed -i ‘s/^ *//’ output

awk -F ‘[()]’ ‘$1 ( 21.07.19 16:12:49 )

Раз тут идет звездная война, а ТС, как я понимаю, ничего не понимает, то если дать почти готовое решение, это ничего не изменить в балансе темных и светлых сил. «` cut -d: -f2 | sort | uniq -c «` И вообще, причем тут баш, сед, авк и другие. Задача именно на понимание.

Ну ты понял, что я ошибся на счет теба. Успехов.

Возможно для больших объемов данных не пойдет и есть решения изящнее и производительнее, но для моего случая и это сработает.

Это точно будет попроизводительнее перелопачивания на баш.

Хорошо, если так можно сделать в bash, сходу и без лишних телодвижений. Я не в курсе и выдал сходу, по памяти.

Здесь sed-ом сначала удаляю пробелы вначале строки, потом с помощью awk по оставляю только строки где количество совпадений меньше заданного (значение в первом поле ( 21.07.19 17:05:25 )

Мне количество совпадений важно обязательно считать в переменную т.к. я потом произвожу с ней математическое действие. Где ты производишь мат. действия? Если в баше, то читай сразу в баш и фильтруй там.

Мне количество совпадений важно обязательно считать в переменную т.к. я потом произвожу с ней математическое действие.

Где ты производишь мат. действия? Если в баше, то читай сразу в баш и фильтруй там.

Мне количество совпадений важно обязательно считать в переменную т.к. я потом произвожу с ней математическое действие.

Спасибо) Протестировал данное решение тоже, все работает.

Только вот выдает строки с совпадениями n не только те, которые меньше заданного значения, но и которые равны этому значению.

Для простых обработок текста есть специальный язык.

Только вот выдает строки с совпадениями n не только те, …

Ясно, пациент полный ноль в баше.

Раз мы для тебя стараемся, сделай для нас что-нибудь. Например, какая самая популярная фамилия?

Только вот выдает строки с совпадениями n не только те, которые меньше заданного значения, но и которые равны этому значению.

Потому там и 4, а не 5. Но если вам для зачёта надо, то поменяйте le, на lt.

Спасибо за пример, познавательно.

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

Не, я не сдаю зачеты, я для своих задач пишу и учусь)

Думаю разобрался бы, выше был пример с -t вместо -e и читал я ранее, что -e это equal, но в любом случае спасибо за поправку.

И вообще всем отписавшимся — спасибо большое за то что подсказали как можно решить задачу разными способами. Добра вам всем. Хорошо, что есть такие отзывчивые люди, которым не лень кому-то менее опытному подсказать)

p.s. ну не полный ноль, скрипты пишу какие-то для себя, повышаю сложность. Но вот с массивами очень плотно пока не работал, знакомлюсь как раз.

На будущее — прочитай Advanced Bash Scripting Guide. Он есть и на русском(правда устаревший перевод), но тебе хватит. Оттуда и будет понятна в чём разница между -lt и -le и где можно обойтись встроенными средствами bash(если переносимость на другие шеллы не планируется), а где надо подключать внешние программы.

Ну а потом — только практика. И чтение чужого кода, да.

Правда отдельной программой не очень удобно

хочется все в одном файле уместить.

ну это так себе хотелка. Не зря индустрия больше полусотни лет разбивает программы на осмысленные части. Но пока твой скрипт не слишком велик программу на awk можно внедрить прямо в него

А вот не соглашусь. Сравните свой код и мой чуть выше. Есть разница? Казалось бы в принципе почти одно и тоже и даже может awk тут будет и быстрее. Но, это пока вам не понадобится потом работать с полученными переменными, особенно если надо будет обрабатывать чуть ли весь ассоциативный массив гораздо дальше, чем можно поместить в этот внедренный код в сложный скрипт.

Читайте также:  Файл эксель открывается с иероглифами mac os

Но, это пока вам не понадобится потом работать с полученными переменными

Объявление запрошенных ТСом переменных в рамках этого скрипта, думаю, излишне (либо мало данных). Что будет, если попадется 2 фамилии с n ★★★★★ ( 21.07.19 23:40:04 )
Последнее исправление: YAR 21.07.19 23:44:10 (всего исправлений: 2)

Что будет, если попадется 2 фамилии с n ★★★★★ ( 21.07.19 23:57:07 )

смысл тогда в awk
Где удобство и скорость?

По удобству — пусть каждый под задачу выбирает удобный для себя вариант. По скорости — awk будет быстрее на больших объемах данных.

Если у ТСа задача все равно подразумевает использование баша (некие математические операции с переменными — и да, а зачем тут баш?) — это не повод решать все исключительно средствами баша, благо подзадачи можно реализовать различными средствами.

По скорости — awk будет быстрее на больших объемах данных.

Да с чего бы это было б сильно заметно? Оба языка, что bash, что awk работают примерно одинаково — парсят текст, создают дерево разбора и его интерпретируют. Я знаю, что там внутри и даже правил и то и другое. У awk есть хорошее преимущество, когда надо обрабатывать входные строки через regex-ы. Когда же у нас задача разбить входные строки на два поля, то применение awk как правило только доказывает непрофессионализм пишущего.

Страдаю какой-то херней вместо приготовления ужина

Да с чего бы это было б сильно заметно?

Страдаю какой-то херней вместо приготовления ужина

Дык. Аж целых 2 минуты жевало, а с первого коммента — уже более 2 часов. Если вам жалко 2 минут на 121Мб, то перепишите на C. Не удивлюсь, что bash тормозит на генерации ассоциативного индекса.

На всякий случай, напоминаю, что я никогда не говорил, что bash на этой задаче может быть быстрее. Я говорил, что если вам понадобится потом эти данные, то встраивание другого интерпретатора в скрипт неудобно и будет скорее всего медленнее. Ну в самом деле, вот пусть у вас 100M будет по 4 имен у фамилий и только одно 5. Ну прогоните через пайп и while read.

Да с чего бы это было б сильно заметно?
я никогда не говорил, что bash на этой задаче может быть быстрее.

Это не «не сильно заметно». Это не «чуть быстрее». Это разница в 200 раз.

Чем что? 2 последовательных цикла на bash по 3 минуты будут быстрее, чем 0.7 секунды на mawk + 3 минуты на bash? Ну ок.

Дальше можно было не писать:

Когда же у нас задача разбить входные строки на два поля, то применение awk как правило только доказывает непрофессионализм пишущего

Это не «не сильно заметно». Это не «чуть быстрее». Это разница в 200 раз.

Как вы предсказуемы. На реальных данных, когда вообще имеет смысл пользоваться скриптами, разница в долях секунд не заметна.

А вот это уже подлог. Я вам предлагал обработать задачу awk, а потом закачать весь массив через read. Собственно данных уже достаточно, чтобы увидеть, что будет медленнее.

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

А вот как это сделать в контексте вашего примера никак не разберусь. Подключать еще один массив?

Справедливости ради, обсуждалось абстрактное условие: «если вдруг. » 🙂

Так как в bash нет многомерных массивов, а их ручная эмуляция весьма кривая как по виду кода так и по скорости, то новые массивы обычно наилучшее решение. Если б не одно но, которое у вас: ассоциативный массив у вас не сохраняет порядок следования входным данным и придётся решать задачу конкретно по ситуации, может даже вначале заполнять данными обычные, а потом отдельно высчитывать с ассоциативными.

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

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

Если подключать БД, то вероятно одним скриптом я уже не справлюсь?

Примерно в этом ключе и думал.

Либо с полученной переменной потом в цикле считать все строки, которые ее содержат.

Не надо строить массивы в баше при обработке реальных данных, ты столкнешься с тем, что у баш нет эффективных по скорости и по потреблению памяти структур данных для работы с такими объемами данными.

Поэтому используй баш как запускалку подходящих для этого программ. Не надо считать математику в баш.

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

Все промежуточные файлы можно скоратить направив через пайпы следующей команде.

Чувствствуешь, что во всем этом практически не используется баш, тупое использование спец-инструментов, и все это есть закат солнца вручную — имитация субд.

Источник

Оцените статью