Необходимо использовать termcap(5)
функция. В странице справочника на некоторых Нельдах говорится, что этот инструмент устаревший и использовать terminfo
, но это все еще доступно на других (и terminfo
более сложно).
Что еще более важно, less
использование termcap
.
less
Я делаю следующее так, чтобы less
и man
(который использует less
) будет иметь цвет:
$ cat ~/.LESS_TERMCAP
export LESS_TERMCAP_mb=$(tput bold; tput setaf 2) # green
export LESS_TERMCAP_md=$(tput bold; tput setaf 6) # cyan
export LESS_TERMCAP_me=$(tput sgr0)
export LESS_TERMCAP_so=$(tput bold; tput setaf 3; tput setab 4) # yellow on blue
export LESS_TERMCAP_se=$(tput rmso; tput sgr0)
export LESS_TERMCAP_us=$(tput smul; tput bold; tput setaf 7) # white
export LESS_TERMCAP_ue=$(tput rmul; tput sgr0)
export LESS_TERMCAP_mr=$(tput rev)
export LESS_TERMCAP_mh=$(tput dim)
export LESS_TERMCAP_ZN=$(tput ssubm)
export LESS_TERMCAP_ZV=$(tput rsubm)
export LESS_TERMCAP_ZO=$(tput ssupm)
export LESS_TERMCAP_ZW=$(tput rsupm)
export GROFF_NO_SGR=1 # For Konsole and Gnome-terminal
И затем в моем ~/.bashrc
, Я делаю это:
# Get color support for 'less'
export LESS="--RAW-CONTROL-CHARS"
# Use colors for less, man, etc.
[[ -f ~/.LESS_TERMCAP ]] && . ~/.LESS_TERMCAP
Примечание: См. документацию относительно LESS_TERMCAP_*
переменные? поскольку, как это работает.
Следующее должно работать:
$ sed 's/\(.\)/\1\n/g' text.txt | sort | uniq -c
Во-первых, мы вставляем новую строку после каждого символа, помещая каждый символ на его собственную строку. Затем мы сортируем его. Затем мы используем команду uniq для удаления дубликатов, снабжая префиксом каждую строку количество случаев того символа.
Для сортировки списка по частоте передайте это все по каналу в sort -nr
.
Решением Steven является хорошее, простое. Это не таким образом производительно для очень больших файлов (файлы, которые не подходят удобно приблизительно к половине Вашей RAM) из-за шага сортировки. Вот awk версия. Это также немного более сложно, потому что это пытается сделать правильную вещь для нескольких специальных символов (новые строки, '
, \
, :
).
awk '
{for (i=1; i<=length; i++) ++c[substr($0,i,1)]; ++c[RS]}
function chr (x) {return x=="\n" ? "\\n" : x==":" ? "\\072" :
x=="\\" || x=="'\''" ? "\\" x : x}
END {for (x in c) printf "'\''%s'\'': %d\n", chr(x), c[x]}
' | sort -t : -k 2 -r | sed 's/\\072/:/'
Вот решение для Perl на том же принципе. Perl имеет преимущество способности отсортировать внутренне. Также это не будет правильно считать дополнительную новую строку, если файл не закончится в символе новой строки.
perl -ne '
++$c{$_} foreach split //;
END { printf "'\''%s'\'': %d\n", /[\\'\'']/ ? "\\$_" : /./ ? $_ : "\\n", $c{$_}
foreach (sort {$c{$b} <=> $c{$a}} keys %c) }'
Медленная, но относительно -дружественная к памяти версия, использующая ruby. Около дюжины МБ оперативной памяти, независимо от размера ввода.
# count.rb
ARGF.
each_char.
each_with_object({}) {|e,a| a[e] ||= 0; a[e] += 1}.
each {|i| puts i.join("\t")}
ruby count.rb < input.txt
t 20721
d 20628
S 20844
k 20930
h 20783
... etc
Более очевидное решение, которое я использую для подсчета появления символов в файле:
cat filename | grep -o. | sort | uniq -c | sort -bnr
направляет вывод в grep
, который затем печатает каждый символ в одной строке | sort
затем перепечатывает каждый символ столько раз, сколько раз он появляется в файле | uniq
подсчитывает количество вхождений | sort -n
снова сортирует этот ввод, по номеру
С файлом, содержащим текст «Арахисовое масло и желе заставили пожилую женщину задуматься о своем прошлом».
Выход:
13
9 e
7 d
5 s
5 a
4 o
4 h
... and more
В первой строке будет указано количество пробелов в файле, вы можете отфильтровать это, если хотите, используяtr -d " "
Простой и относительно производительный:
fold -c1 testfile.txt | sort | uniq -c
Просто скажите fold
обернуть (, т.е. вставить новую строку )после каждого 1 символа.
Как проверяли:
find. -type f -name '*.[hc]' -exec cat {} >> /tmp/big.txt \;
в нескольких кодовых базах. LC_ALL=C
Время выполнения в порядке убывания:
sed|sort|uniq
(https://unix.stackexchange.com/a/5011/427210):102,5 с fold|sort|uniq
решение :59,3 сек fold|sort|uniq
решение с опцией --buffer-size=12G
дляsort
:38,9 сек fold|sort|uniq
, с параметрами --buffer-size=12G
и --stable
, заданными дляsort
:37,9 сек perl
(https://unix.stackexchange.com/a/5013/427210):34,0 сек. :-)
sed 's/\(.\)/\1\'$'\n/g' text.txt
– mb21 20.12.2013, 11:08