Например, у меня есть файл 1.txt
, который содержит:
Moscow
Astana
Tokyo
Ottawa
Я хочу посчитать количество всех символов как:
a - 4,
b - 0,
c - 1,
...
z - 0
command-line
bash
text-processing
Set-хх
источник
источник
Ответы:
Вы можете использовать это:
sed
Часть помещает символ новой строки после каждого символа. Тогда мыsort
выводим по алфавиту. И, наконец,uniq
подсчитывает количество случаев.-i
Флагuniq
может быть опущен , если вы не хотите случай нечувствительности.источник
sort -k 2
алфавитно-цифровой список.sed -e $'s/\(.\)/\\1\\\n/g'
(см. Также stackoverflow.com/a/18410122/179014 )| sort -rnk 1
. И если вы имеете дело с очень большими файлами, как я, вы можете просто взять несколько тысяч строк, чтобы получить прокси для фактических подсчетов:cat 1.txt | shuf -n 10000 | sed 's/\(.\)/\1\n/g' | sort | uniq -ic | sort -rnk 1
Немного поздно, но для завершения набора, другой подход python (3), отсортированный результат:
объяснение
Прочитайте файл, пропустите пробелы и вернитесь как «символы»:
Создайте (отсортированный) набор уникальных элементов:
Подсчитайте и напечатайте вхождение для каждого из символов:
Как пользоваться
chars_count.py
Запустите его с файлом в качестве аргумента:
если скрипт исполняемый, или:
если это не так
источник
По умолчанию в AWK F IELD S eparator (FS) является пространством или вкладки . Так как мы хотим подсчитать каждый символ, нам нужно будет переопределить FS в none (
FS=""
), чтобы разделить каждый символ в отдельной строке и сохранить его в массив, а в конце внутриEND{..}
блока вывести их общее количество вхождений с помощью следующей команды awk :В
{for (i=1;i<=NF;i++) a[$i]++} ... FS="" ...
блоке мы просто разбиваем персонажей. Ив
END{for (c in a) print c,a[c]}
блоке мы зацикливаемся на массивa
и печатаем в нем сохраненный символprint c
и его количество вхожденийa[c]
источник
Сделайте
for
цикл для всех символов, которые вы хотите посчитать, и используйтеgrep -io
для получения всех вхождений символа и игнорирования регистра, а такжеwc -l
для подсчета экземпляров и печати результата.Как это:
Скрипт выводит это:
РЕДАКТИРОВАТЬ после комментария
Чтобы создать цикл для всех печатных символов, вы можете сделать это:
Это будет считать все символы ANSI от 32 до 126 - это наиболее часто читаемые. Обратите внимание, что это не использует игнорировать регистр.
Выход из этого будет:
источник
i
из grep. (в вашем вопросе вы имели только 3 в ожидаемом результате)grep
на весь вход неоднократно.Здесь другое решение (в awk) ...
источник
cat file | awk '...'
: можно прямо сказатьawk '...' file
.Следующий
perl
oneliner сделает подсчет. Я поместил регулярное выражение в контекст списка (чтобы получить количество совпадений) и поместил это в скалярный контекст:источник
perl -Mfeature=say -e '$a=join("",<>);say join(",\n", map { sprintf("%s - %d", $_, ($d=()=$a=~/$_/gi)); } ("a".."z"))'
Вот решение с использованием Python:
Здесь мы использовали класс
collections
модуляCounter
для подсчета количества вхождений каждого символа, затем для целей печати мы использовалиstring
модуль, чтобы получить все строчные буквы по переменнойstring.lowercase
.Сохраните приведенный выше скрипт в файле, присвоив ему любое имя, например
count.py
. Теперь из того же каталога , в котором сохранен файл , который вы можете просто запустить ,python count.py
чтобы выполнить файл, из любого другого использования каталога абсолютного пути к файлу для его выполнения естьpython /absolute/path/to/count.py
.источник
Некоторое время назад я написал для этого C-программу, потому что мне нужно было просматривать большие файлы и производить некоторую статику.
скомпилировать с (при условии, что исходный код находится в
character-distribution.c
):бежать с:
Если у вас нет готового компилятора C, установите GCC:
источник
Аналогичное решение для @heemayl, с более узким кодом, которое работает на Python 2.7 и Python 3.
Первое утверждение,
count = collections.Counter(…)
делает всю настоящую работу.fileinput.input()
читает каждую строку ввода, которая может быть передана через stdin или в качестве аргументов командной строки.*
заставляет его рассматривать символ за раз, а не строку за раз.count = Counter(…)
эффективно рассчитывает вхождения каждого символа за один проход и сохраняет результат вcount
переменной.Вторая строка просто печатает результаты.
'{} - {}'.format(c, count[c] + count[c.upper()]) for c in string.ascii_lowercase
Составляет список каждого персонажа и его количество.print(',\n'.join(…))
помещает его в желаемый формат: по одному на строку, разделенные запятыми, но без запятой в последней строке.источник
GNU awk 4.1
Если у вас есть более ранняя версия GNU awk, вы можете использовать
for (c in b) print c, b[c]
.источник
Вот ответ, используя рубин. Это делается путем изменения строки в уникальный список различных символов и использования метода count для каждого из них.
источник