Считайте общее количество случаев с помощью grep

Вот несколько вещей, которые можно сделать:

Редакторы + код
У большого количества редакторов есть поддержка подсветки синтаксиса. vim и emacs имейте его на по умолчанию. Можно также включить его под nano.

Вы можете также код выделения синтаксиса терминала при помощи Pygments как инструмент командной строки.

grep
grep --color=auto выделения все соответствия. Можно также использовать export GREP_OPTIONS='--color=auto' сделать это персистентным без псевдонима. Если Вы используете --color=always, это будет использовать цвет, передавая по каналу, который путает вещи.

ls

ls --color=always

Цвета, указанные:

export LS_COLORS='rs=0:di=01;34:ln=01;36:mh=00:pi=40;33'

(подсказка: dircolors может быть полезным),

PS1
Можно установить PS1 (приглашение оболочки) использовать цвета. Например:

PS1='\e[33;1m\u@\h: \e[31m\W\e[0m\$ '

Произведет PS1 как:

[желтый] lucas@ubuntu: [красный] ~ [нормальный] $

Можно стать действительно творческими с этим. Как идея:

PS1='\e[s\e[0;0H\e[1;33m\h    \t\n\e[1;32mThis is my computer\e[u[\u@\h:  \w]\$ '

Помещает панель наверху Вашего терминала с некоторой случайной информацией (Для лучших результатов, также используйте alias clear="echo -e '\e[2J\n\n'".)

Избавление от escape-последовательностей

Если что-то застревает, производя цвет, когда Вы не хотите его к, я использую это sed строка для разделения escape-последовательностей:

sed "s/\[^[[0-9;]*[a-zA-Z]//gi"

Если Вы хотите более подлинный опыт, можно также избавиться от строк, запускающихся с \e[8m, который дает терминалу команду скрывать текст. (Не широко поддерживаемый.)

sed "s/^\[^[8m.*$//gi"

Также обратите внимание, что те ^ [s должны быть фактическим, литеральным ^ [s. Можно ввести их путем нажатия ^V^ [в ударе, который является Ctrl + V, Ctrl + [.

228
22.05.2015, 13:12
7 ответов

grep's -o только произведет соответствия, игнорируя строки; wc может считать их:

grep -o 'needle' file | wc -l

Это будет также соответствовать 'иглам' или 'мультиигле'.

Распознать только отдельные слова:

grep -o '\bneedle\b' file | wc -l
# or:
grep -o '\<needle\>' file | wc -l
328
27.01.2020, 19:27
  • 1
    Обратите внимание, что это требует GNU grep (Linux, Cygwin, FreeBSD, OSX). –  Gilles 'SO- stop being evil' 15.05.2011, 17:37
  • 2
    @wag, Что делает волшебство \b и \B здесь? –  Geek 12.06.2014, 11:36
  • 3
    @Geek \b соответствует границе слова, \B соответствует НЕ границе слова. Ответ выше был бы более корректным, если бы он использовал \b в обоих концах. –  Liam 26.09.2015, 00:02
  • 4
    Для количества случаев на строку, объединения с grep-n опция и uniq-c... grep - нет '\<игла \>' файл | uniq-c –  jameswarren 07.10.2016, 16:56
  • 5
    @jameswarren uniq только удаляет смежные идентичные строки, Вы должны sort прежде, чем питаться к uniq если Вы не уже уверены, что дубликаты всегда будут сразу смежны. дата создания –  tripleee 03.11.2016, 14:21

Если у Вас есть GNU grep (всегда на Linux и Cygwin, иногда в другом месте), можно считать выходные строки от grep -o: grep -o needle | wc -l.

С Perl вот несколько способов, которыми я нахожу более изящными, чем Ваш (даже после того, как он фиксируется).

perl -lne 'END {print $c} map ++$c, /needle/g'
perl -lne 'END {print $c} $c += s/needle//g'
perl -lne 'END {print $c} ++$c while /needle/g'

Только с инструментами POSIX один подход, если это возможно, должен разделить вход на строки с единственным соответствием прежде, чем передать его grep. Например, если Вы ищете целые слова, затем сначала превращаете каждый несловесный символ в новую строку.

# equivalent to grep -ow 'needle' | wc -l
tr -c '[:alnum:]' '[\n*]' | grep -c '^needle$'

Иначе нет никакой стандартной команды, чтобы внести свою лепту обработки текста, таким образом, необходимо обратиться к sed (если Вы - мазохист), или awk.

awk '{while (match($0, /set/)) {++c; $0=substr($0, RSTART+RLENGTH)}}
     END {print c}'
sed -n -e 's/set/\n&\n/g' -e 's/^/\n/' -e 's/$/\n/' \
       -e 's/\n[^\n]*\n/\n/g' -e 's/^\n//' -e 's/\n$//' \
       -e '/./p' | wc -l

Вот использование простого решения sed и grep, который работает на строки или даже регулярные выражения книгой, но перестал работать в нескольких угловых случаях с привязанными шаблонами (например, это находит два случаев ^needle или \bneedle в needleneedle).

sed 's/needle/\n&\n/g' | grep -cx 'needle'

Обратите внимание, что в sed заменах выше, я использовал \n означать новую строку. Это стандартно в части шаблона, но в тексте замены, для мобильности, новой строки обратной косой черты замены для \n.

18
27.01.2020, 19:27

Другое решение с помощью awk и needle как разделитель полей:

awk -F'^needle | needle | needle$' '{c+=NF-1}END{print c}'

Если Вы хотите соответствовать needle сопровождаемый пунктуацией, измените разделителя полей соответственно т.е.

awk -F'^needle[ ,.?]|[ ,.?]needle[ ,.?]|[ ,.?]needle$' '{c+=NF-1}END{print c}'

Или использование класс: [^[:alnum:]] охватить все не альфа-символы.

3
27.01.2020, 19:27
  • 1
    Обратите внимание, что это требует awk, который поддерживает regexp разделителей полей (таких как GNU awk). –  Gilles 'SO- stop being evil' 15.05.2011, 17:38

Ваш пример только распечатывает количество случаев на строку а не общее количество в файле. Если это - то, что Вы хотите, что-то вроде этого могло бы работать:

perl -nle '$c+=scalar(()=m/needle/g);END{print $c}' 
1
27.01.2020, 19:27
  • 1
    Вы правы - мой пример только считает происшествия в первой строке. –   06.02.2011, 17:49

Это - мое чистое решение для удара

#!/bin/bash

B=$(for i in $(cat /tmp/a | sort -u); do
echo "$(grep $i /tmp/a | wc -l) $i"
done)

echo "$B" | sort --reverse
1
27.01.2020, 19:27

Если, как и я, вы действительно хотели "оба; каждый ровно один раз", (на самом деле это "либо; дважды") тогда все просто:

grep -E "thing1|thing2" -c

и проверьте выход 2 .

Преимущество этого подхода (если только один раз - это то, что вам нужно)) заключается в том, что он легко масштабируется.

5
27.01.2020, 19:27

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

Только мой bash -, один вкладыш -, решение следующее:

grep -o -E 'borp|flarb' flarb.log  | sort | uniq -c
 910 borp
9090 flarb
0
05.11.2021, 17:39

Теги

Похожие вопросы