计算字符串中子字符串出现的次数

Edu*_*cio 6 grep bash sed awk shell-script

如何使用 Bash 计算字符串中子字符串的出现次数?

例子:

我想知道这个子字符串有多少次:

Bluetooth
         Soft blocked: no
         Hard blocked: no
Run Code Online (Sandbox Code Playgroud)

...出现在这个字符串中...

0: asus-wlan: Wireless LAN
         Soft blocked: no
         Hard blocked: no
1: asus-bluetooth: Bluetooth
         Soft blocked: no
         Hard blocked: no
2: phy0: Wireless LAN
         Soft blocked: no
         Hard blocked: no
113: hci0: Bluetooth
         Soft blocked: no
         Hard blocked: no
Run Code Online (Sandbox Code Playgroud)

注意我:我已经尝试了几种使用 sed、grep、awk 的方法......当我们有带有空格和多行的字符串时,似乎没有任何效果。

注意 II:我是 Linux 用户,我正在尝试一种解决方案,该解决方案不涉及安装 Linux 发行版中常见的应用程序/工具之外的应用程序/工具。


重要的:

我想要类似于下面的假设示例。在这种情况下,我们使用两个Shell 变量 (Bash)

例子:

STRING="0: asus-wlan: Wireless LAN
         Soft blocked: no
         Hard blocked: no
1: asus-bluetooth: Bluetooth
         Soft blocked: no
         Hard blocked: no
2: phy0: Wireless LAN
         Soft blocked: no
         Hard blocked: no
113: hci0: Bluetooth
         Soft blocked: no
         Hard blocked: no"

SUB_STRING="Bluetooth
         Soft blocked: no
         Hard blocked: no"

awk -v RS='\0' 'NR==FNR{str=$0; next} {print gsub(str,"")}' "$STRING" "$SUB_STRING"
Run Code Online (Sandbox Code Playgroud)

注意:我们使用 awk 只是为了说明!

Sté*_*las 8

perl

printf '%s' "$SUB_STRING" |
  perl -l -0777 -ne '
    BEGIN{$sub = <STDIN>}
    @matches = m/\Q$sub\E/g;
    print scalar @matches' <(printf '%s' "$STRING")
Run Code Online (Sandbox Code Playgroud)

有了bash独自一人,你总是可以这样做:

s=${STRING//"$SUB_STRING"}
echo "$(((${#STRING} - ${#s}) / ${#SUB_STRING}))"
Run Code Online (Sandbox Code Playgroud)

$s包含删除了$STRING其中的所有出现$SUB_STRING。我们找出的数量$SUB_STRING通过计算之间的字符数之差被拆除,且s$STRING$s和的长度除以$SUB_STRING本身。

POSIXly,您可以执行以下操作:

s=$STRING count=0
until
  t=${s#*"$SUB_STRING"}
  [ "$t" = "$s" ]
do
  count=$((count + 1))
  s=$t
done
echo "$count"
Run Code Online (Sandbox Code Playgroud)


Sap*_*ick 6

如果子字符串不包含换行符:

echo -n STRING | grep -Fo SUBSTRING | wc -l
Run Code Online (Sandbox Code Playgroud)

  • 很好的解决方案。只需一个小调整,使用 grep -Fo: `echo $STRING | grep -Fo 子字符串 | 厕所-l` (2认同)