如何使用 Bash 计算字符串中子字符串出现的次数?
例子:
我想知道这个子字符串出现了多少次......
Bluetooth
Soft blocked: no
Hard blocked: no
...出现在这个字符串中...
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
注一:我尝试过 sed、grep、awk 等多种方法......当我们有带有空格和多行的字符串时,似乎没有任何方法起作用。
注二:我是一名 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"
笔记:我们使用 awk 只是为了说明!
答案1
我认为可以用 做得更好awk
,但这是我能提供的最好的。
grep -zo "Bluetooth\s*Soft blocked: no\s*Hard blocked: no" file_name | grep -c "Bluetooth"
-z
将grep
整个文件视为一行。
-o
仅写入与字符串匹配的输出,而不是整行。
(在我们的例子中,-z
这意味着整个文件)
\s
匹配空白字符和新行。
第二个实例grep
将仅在第一个调用的输出中搜索单词“蓝牙” grep
。
-c
写入grep
匹配的正则表达式的计数,而不是匹配本身。
答案2
您想如何匹配有点不清楚(上面评论中的附加示例没有任何意义),但是假设您将字符串块与网络信息一起存储在文件内部,将string
子字符串块存储在文件内部substring
。
使用以下方法,您将获得我所理解的您所期望的结果:2 场比赛。
cat string | tr -s " " | tr '\n' '@' | grep -o "$(cat substring | tr -s " " | tr '\n' '@')" | wc -l
本质上,两个字符串都被压缩为一行,忽略空格或制表符,并将换行符转换为@
。使用语法,我们打印找到的模式的grep -o
所有出现次数( )。-o
但是,不清楚在您的示例中,您是否希望它匹配 0 次(精确位置匹配)或 2 次(忽略前置文本)。这是一个与责任发布这里;难道我们误解了你的意图?
如果您尝试计算二维文本片段的匹配数,则可能需要模糊 grep。