Как я могу записать количество каналов ('|')? - PullRequest
2 голосов
/ 05 марта 2009

Я пробовал:

 grep -c "\|" *.* 

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

Как мне это сделать?

Ответы [ 5 ]

10 голосов
/ 05 марта 2009

Вы можете использовать tr(1), чтобы удалить все символы, не относящиеся к трубе, а затем использовать wc(1), чтобы получить общее количество:

cat *.* | tr -d -c '|' | wc -c
6 голосов
/ 05 марта 2009

Это нелогично, но в большинстве регулярных выражений Unix экранирование | делает его оператором or. Таким образом, ваша строка на самом деле соответствует «ничего или ничего» (вы можете проверить это, добавив несколько альтернатив с обеих сторон). Просто используйте

grep -c "|" *.*

Во-вторых, grep считает строки, а не вхождения символов. Вы можете использовать другой инструмент; или, если вы настаиваете на grep, вы можете поставить каждый "|" на своей собственной линии. Например, с помощью sed:

sed 's/|/|\n/g' *.*

Примечание: если вы используете sed, я советую lot тестирования, чтобы убедиться, что он делает то, что вы думаете, что он делает. Мне нужно было именно тогда.

Наконец, объедините ингредиенты:

cat *.*  |  sed 's/|/|\n/g'  |  grep -c "|"

К сожалению, это может не сработать, поскольку вы, вероятно, не используете unix (из-за *.*). Но, надеюсь, это объясняет проблему, которую я всегда нахожу странно обнадеживающей.

3 голосов
/ 05 марта 2009

Другой вариант, использующий Perl:

perl -e 'while(<>){$c+=tr/|/|/};print "$c\n"' *

В формате не одной строки это:

while(<>){
    $c += tr/|/|/
}
print "$c\n"

Строка while(<>){ - это волшебство Perl для чтения строк из файлов команды или из STDIN. Вы привыкаете к этому через некоторое время. Сама строка переходит в переменную с именем $_, которая является параметром по умолчанию для многих команд Perl. Например, tr, который работает почти так же, как tr(1), по умолчанию работает на $_. Я помещаю свои результаты в глобальную переменную с именем $c. (В полной программе лучше объявить ее лексической переменной с my $c = 0; вне цикла.) Оператор += добавляет результат команды tr (количество символов канала в данном случае) к текущему значение $c.

Просто использовать tr(1) явно проще. ; -) * 1 021 *

Использование *.* - это DOSism, который вы вряд ли захотите использовать на UNIX-подобной платформе.

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

$ echo '||||
|||||' | perl -e 'while(<>){$c+=tr/|/|/};print "$c\n"'
9
0 голосов
/ 20 мая 2014

Если вы хотите найти количество труб, то

fgrep -o "|" | wc -l

Если вы хотите найти количество строк хотя бы с одним каналом, то

fgrep -c "|"
0 голосов
/ 05 марта 2009

1001 * попробовать *

grep -c "\|" *.*

и прочитайте несколько уроков о bash

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...