У меня есть 100 миллионов строк в моем файле.
Каждая строка имеет только один столбец.
например
aaaaa
bb
cc
ddddddd
ee
Я хотел бы перечислить количество символов
Нравится
2 character words - 3
5 character words - 1
7 character words - 1
и т.п.
Есть ли простой способ сделать это в терминале?
text-processing
Гири
источник
источник
Ответы:
Первый
awk
фильтр просто напечатает длину каждой строки в вызываемом файлеfile
. Я предполагаю, что этот файл содержит одно слово в строке.В
sort -n
(сортировка линии с выходаawk
численно в порядке возрастания) иuniq -c
(подсчитать количество раз , каждая строка происходит последовательно) , а затем создаст следующий вывод из что для приведенных данных:Затем он анализируется вторым
awk
сценарием, который интерпретирует каждую строку как «число X строк, содержащих символы Y» и выдает желаемый результат.Альтернативное решение состоит в том, чтобы сделать все это
awk
и вести подсчет длин в массиве. Это компромисс между эффективностью, удобочитаемостью / простотой понимания (и, следовательно, удобством обслуживания), какое решение является «лучшим».Альтернативное решение:
источник
Еще один способ сделать все это в
awk
одиночкуwords[length()]++
использовать длину строки ввода в качестве ключа, чтобы сохранить счетEND{for(k in words)print k " character words - " words[k]}
после обработки всех строк выведите содержимое массива в нужном форматеСравнение производительности, выбранные номера являются лучшими из двух прогонов
Если файл содержит только символы ASCII,
Не уверен, почему время
perl
не сильно изменилось, возможно, кодировка должна быть установлена другим способомисточник
length
без()
прекрасно работает здесь, поэтому было бы излишним добавлять фигурные скобки. Я использую GNU awk, хотя.In older versions of awk, the length() function could be called without any parentheses. Doing so is considered poor practice, although the 2008 POSIX standard explicitly allows it, to support historical practice. For programs to be maximally portable, always supply the parentheses
Вот
perl
эквивалент (с - необязательно - сортировка):источник
{$a<=>$b}
послеsort
исправит это. В качестве альтернативы можно использовать обычный массив с числовыми ключами и просто пропустить любые ключи, где значение равно нулю / не определено.Альтернативой один вызов GNU AWK, используя Printf :
Основной алгоритм просто собирает количество символов в массиве. Конечная часть печатает собранные отсчеты в формате printf.
Быстро, просто, один звонок в awk.
Чтобы быть точным: немного больше памяти используется для хранения массива.
Но сортировка не вызывается (индексы числовых массивов устанавливаются так, чтобы их всегда обходили, сортируя вверх с помощью PROCINFO), и только одна внешняя программа:
awk
вместо нескольких.источник
for in
может случиться так, что индексы числовых массивов будут приведены в числовом порядке, по крайней мере, для некоторых значений или в некоторых реализациях awk, но это не обязательно, не традиционно, и определенно не универсально. Это часто случается для крошечных наборов, таких как 2 или 3 или, может быть, 4; Попробуйте 10 или 20 на каждом awk, к которому у вас есть доступ (без PROCINFO или WHINY_USERS в gawk), и я держу пари, что $ 50, по крайней мере, один случай не отсортирован.@ind_str_asc
сортирует как строки, которые будут правильными для чисел, только если они все однозначные (как в вашем примере); используйте,@ind_num_asc
если (любые) значения могут быть 10 или больше. И хотя сейчас это не так важно, как раньше, эта функция только gawk 4.0 up .