Bash - 计算字符串中的子字符串

时间:2014-10-06 09:00:06

标签: linux bash shell ubuntu

我正在努力编写一个命令来计算子字符串出现在字符串中的次数。

而不是将代码运行10次以下,我宁愿预先计算子字符串出现的次数并调整"对于"根据其结果:

在这里你可以看到代码:

CommandResult="Interface    Chipset     Driver     mon0    Unknown      iwlwifi - [phy0]wlan0       Unknown     iwlwifi - [phy0]"

for i in `seq 0 9`;
do
  InstanceID="mon"$i

  if echo "$CommandResult" | grep -q "$InstanceID"; then
    echo "found"
  fi
done

任何帮助将不胜感激!

谢谢,

5 个答案:

答案 0 :(得分:5)

随意试试这个号码:

echo "$CommandResult" | tr " " "\n" | grep -c "$InstanceID"

答案 1 :(得分:4)

我使用grep -o从输出中提取所需的字符串:

#!/bin/bash
CommandResult="Interface    Chipset     Driver     mon0    Unknown      iwlwifi - [phy0]wlan0       Unknown     iwlwifi - [phy0]
Interface    Chipset     Driver     mon12    Unknown      iwlwifi - [phy0]wlan0       Unknown     iwlwifi - [phy0]"

for InstanceId in $(grep -o 'mon[0-9]\+' <<< "$CommandResult") ; do
    echo "found $InstanceId "$(grep -c "$InstanceId" <<< "$CommandResult")' times'
done

答案 2 :(得分:2)

你可以这样做:

#!/bin/bash
CommandResult="Interface    Chipset     Driver     mon0    Unknown      iwlwifi - [phy0]wlan0       Unknown     iwlwifi - [phy0]"
InstanceId="mon0";
count=`grep -o "$InstanceId" <<< "$CommandResult" | wc -l`
echo "$InstanceId encountered "$count" times";

答案 3 :(得分:1)

你可以使用:

mon_num=$(airmon-ng | grep -Poc '\bmon\d+\b')
echo here are $mon_num mon interfaces

for m in $(airmon-ng | grep -Po '\bmon\d+\b')
do
        #do something
        echo "this is $m"
done

表示airmon-ng输出:

Interface   Chipset     Driver

mon0        Unknown     iwlwifi - [phy0]
mon1        Unknown     iwlwifi - [phy0]
mon2        Unknown     iwlwifi - [phy0]
wlan0       Unknown     iwlwifi - [phy0]

将打印

here are 3 mon interfaces
this is mon0
this is mon1
this is mon2

答案 4 :(得分:1)

想要分享另一种解决方案。 3,5年后,但迟到总比我想的要好。 ;)

我正在编写一个必须执行相同操作的脚本,即获取字符串中的子串数,并且我最初使用的是count=$(echo '$string' | grep -o ... | wc -l)。 我得到了我想要的东西,但是当循环遍历大约1500个文件时,每个行程只有0 ... 8000行,性能非常糟糕:脚本需要 49分钟才能完成。
所以,我去寻找替代方法并最终找到了这个:

InstanceId="mon0";
tmp="${CommandResult//$InstanceId}"
count=$(((${#CommandResult} - ${#tmp}) / ${#InstanceId}))

在8-9分钟内得到了相同的结果,但是更快。

解释

tmp="${CommandResult//$InstanceId}"

这会从$InstanceId中删除$CommandResult的所有内容,并将其放在tmp中。
实际上我们在这里使用子串替换,缺少替换字符串。子串替换的语法是${string//substring/replacement}(这将替换所有出现的替换子串。)

count=$(((${#CommandResult} - ${#tmp}) / ${#InstanceId}))

这为我们提供$InstanceId$CommandResult的出现次数 ${#string}给出了字符串长度,因此(${#CommandResult} - ${#tmp])是所有$InstanceId出现的长度(请记住,我们从$InstanceId删除了所有$CommandResult,并将结果放在{ {1}})。
然后我们只将长度为$tmp的减法除以得到$InstanceId次出现次数。

有关子字符串替换和字符串长度的更多信息,请参阅例如https://www.tldp.org/LDP/abs/html/string-manipulation.html