2016-09-29 3 views
0

Я хотел бы подсчитать количество вхождений в строке. Например, в этой строке:Подсчитайте количество шаблонов с одной командой

'apache2|ntpd' 

есть 2 разные строки, разделенные | характер. Другой пример:

'apache2|ntpd|authd|freeradius' 

В этом случае есть 4 различных строк, разделенных | характер.

Вы знаете команду оболочки или perl, которая могла бы просто посчитать это для меня?

+0

Вам нужно подсчитать количество вхождений символа трубы, затем добавьте один. – fafl

+0

IN = "[email protected]; [email protected]" почты = $ (эхо $ IN | тр ";" "\ п") для адреса в $ почт сделать эхо «> [$ addr] " done –

ответ

2

Вы можете использовать команду awk, как указано ниже;

echo "apache2|ntpd" | awk -F'|' '{print NF}' 

-F '|' является разделителем поля; NF средства Количество полей

Пример;

[email protected]:/tmp$ echo 'apache2|ntpd|authd|freeradius' | awk -F'|' '{print NF}' 
4 

Вы также можете использовать это;

[email protected]:/tmp$ echo "apache2|ntpd" | tr '|' ' ' | wc -w 
2 
[email protected]:/tmp$ echo 'apache2|ntpd|authd|freeradius' | tr '|' ' ' | wc -w 
4 


tr '|' ' ' : translate | to space 
wc -w : print the word counts 

, если есть пробелы в строке, туалет -w не правильный результат, так

echo 'apac he2|ntpd' | tr '|' '\n' | wc -l 



u[email protected]:/tmp$ echo 'apac he2|ntpd' | tr '|' ' ' | wc -w 
3 --> not correct 
[email protected]:/tmp$ echo 'apac he2|ntpd' | tr '|' '\n' | wc -l 
2 

tr '|' '\n' : translate | to newline 
wc -l : number of lines 
+0

Спасибо за ваш ответ, это решение решило мою просьбу! – PsyKoptiK

+0

Ваш 'tr | wc' не работает, если в строке есть пробелы. –

+0

@gniourf_gniourf: Спасибо, ты прав, я обновил ан. –

-1

Возможно, это поможет вам.

IN="apache2|ntpd" 

mails=$(echo $IN | tr "|" "\n") 

for addr in $mails 
do 
    echo "> [$addr]" 
done 
+0

Пожалуйста, правильно отформатируйте код или добавьте несколько полуколоней. Этот код дает синтаксическую ошибку в том виде, в каком она стоит, и даже если исправления не дают количество полей. – cdarke

1

Do может сделать это только в bash без вызова внешних языков, таких как awk или внешних программ, как grep и tr ,

data='apache2|ntpd|authd|freeradius' 
res=${data//[!|]/} 
num_strings=$((${#res} + 1)) 
echo $num_strings 

Позвольте мне объяснить.

res=${data//[!|]/} удаляет все символы, которые не (это !) трубы (|).

${#res} дает длину результирующей строки.

num_strings=$((${#res} + 1)) добавляет один к количеству труб, чтобы получить количество полей.

Это так просто.

1

другой чистого bash техники с помощью позиционных-параметров

$ userString="apache2|ntpd|authd|freeradius" 
$ printf "%s\n" $(IFS=\|; set -- $userString; printf "%s\n" "$#") 
4 

Благодаря cdarke's предложению из команд, приведенная выше команда может непосредственно хранить счетчик в переменной

$ printf -v count "%d" $(IFS=\|; set -- $userString; printf "%s\n" "$#") 
$ printf "%d\n" "$count" 
4 
+1

Возможно, стоит добавить, что число может быть помещено в переменную с использованием '-v var' в самый левый' printf' (в этом случае вы, вероятно, захотите изменить форматирование на ''% d "', т.е. no новая линия). – cdarke

+0

Он также может быть упрощен до 'count = $ (IFS = \ |; set - $ userString; echo" $ # ")' – cdarke

+1

Вы делаете это неэффективно: для первой формы не требуется дополнительная 'printf' и подстановка процесса: '(IFS = \ |; set - $ userString; printf '% s \ n'" $ # ")' достаточно; во второй форме достаточно просто 'count = $ (IFS = \ |; set - $ userString; printf"% s \ n "" $ # ")'. Теперь сам метод разбит, поскольку он будет терпеть неудачу, если строка содержит соответствующие глобусы (хотя вы можете использовать 'set -f', чтобы отключить глобус, но я бы не рекомендовал его). (продолжение следует) –

1

С wc и расширением параметра :

$ data='apache2|ntpd|authd|freeradius' 
$ wc -w <<< ${data//|/ } 
4 

Используя расширение параметра, все трубы заменяются пробелами. Строка результата передается wc -w для подсчета слов.

Как упоминалось в @gniourf_gniourf, он работает с тем, что сначала выглядит как имена процессов, но будет терпеть неудачу, если строки содержат пробелы.

+0

Это, очевидно, не выполняется, если строка содержит пробелы. –

+0

@gniourf_gniourf Спасибо. Я обновил. – SLePort

0

Вы можете сделать это с grep, как хорошо

echo "apache2|ntpd|authd|freeradius" | grep -o "|" | wc -l 
Output- 
3 

Этот выход является количество труб.

Чтобы получить число-команд

var=$(echo "apache2|ntpd|authd|freeradius" | grep -o "|" | wc -l) 
echo $((var + 1)) 
Output - 
4 
0

Вы можете использовать AWK для подсчета occurrances разделителей +1:

$ awk '{print gsub(/\|/,"")+1}' <(echo "apache2|ntpd|authd|freeradius") 
4 
Смежные вопросы