我想计算一个字符串中出现的次数。例如,在此字符串中:
'apache2|ntpd'
有两个不同的字符串,以|
字符分隔。
另一个例子:
'apache2|ntpd|authd|freeradius'
在这种情况下,有4个不同的字符串以|
字符分隔。
你能知道一个shell或perl命令,它可以为我计算这个吗?
答案 0 :(得分:2)
您可以使用以下awk命令;
echo "apache2|ntpd" | awk -F'|' '{print NF}'
-F' |'是现场分离器; NF表示字段数
实施例
user@host:/tmp$ echo 'apache2|ntpd|authd|freeradius' | awk -F'|' '{print NF}'
4
你也可以使用它;
user@host:/tmp$ echo "apache2|ntpd" | tr '|' ' ' | wc -w
2
user@host:/tmp$ echo 'apache2|ntpd|authd|freeradius' | tr '|' ' ' | wc -w
4
tr '|' ' ' : translate | to space
wc -w : print the word counts
如果字符串中有空格,则wc -w结果不正确,所以
echo 'apac he2|ntpd' | tr '|' '\n' | wc -l
user@host:/tmp$ echo 'apac he2|ntpd' | tr '|' ' ' | wc -w
3 --> not correct
user@host:/tmp$ echo 'apac he2|ntpd' | tr '|' '\n' | wc -l
2
tr '|' '\n' : translate | to newline
wc -l : number of lines
答案 1 :(得分:1)
可以在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,以获得字段数。
就这么简单。
答案 2 :(得分: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
答案 3 :(得分:1)
使用wc
和参数扩展:
$ data='apache2|ntpd|authd|freeradius'
$ wc -w <<< ${data//|/ }
4
使用参数扩展,所有管道都替换为空格。结果字符串将传递给wc -w
以进行字数统计。
正如@gniourf_gniourf所提到的,它最初看起来像进程名称,但如果字符串包含空格则会失败。
答案 4 :(得分: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
答案 5 :(得分:0)
您可以使用awk来计算分隔符的出现次数+1:
$ awk '{print gsub(/\|/,"")+1}' <(echo "apache2|ntpd|authd|freeradius")
4
答案 6 :(得分:-1)
可能会对你有帮助。
IN="apache2|ntpd"
mails=$(echo $IN | tr "|" "\n")
for addr in $mails
do
echo "> [$addr]"
done