繁体   English   中英

遍历字符串并在shell中查找某些字符

[英]Loop through string and look for certain characters in shell

可以说我将以下字符串存储在变量中:

string =“ 1245aaa./ ssasaaa * kjdsaaa”

有没有办法以某种方式遍历该字符串,发现它包含3个“单词”,可以说用空格隔开,并且最大“ a”的单词是第二个单词,总共有4个“ a”在第二个字?

我一直在尝试谷歌这样的事情,但没有运气。

另一种方法是为至少n个(在您的示例中为4个) a的行进行grepping。
首先,您必须找到需要grep的号码。
步骤(在评论中要求):
通过用换行符替换( tr ,translation)空格,将字符串中的单词分成几行。

echo "${string}" | tr " " "\n"

使用sed 's/old/new/g' ,可以用新字符串g(全局)用旧字符串(模式)替换(替换)旧字符串(模式)。 因此,您可以echo "Have all characters a banned" | sed 's/a//g' echo "Have all characters a banned" | sed 's/a//g' 您要替换字符a以外的所有字符。 所述^[^a]表示not ,在[]的一类的字符。

echo "${string}" | tr " " "\n" | sed 's/[^a]//g'

您可以通过排序找到a的最长字符串。 排序后,最后一行将最多。 使用tail -1您可以得到最后一行:

echo "${string}" | tr " " "\n" | sed 's/[^a]//g'|sort | tail -1

现在将结果放入变量。 您可以使用var=$(command)将另一个(一组)unix命令的输出分配给变量,请注意,不要在=号周围添加空格( var = $(xxx)会失败)。

most_a=$(echo "${string}" | tr " " "\n" | sed 's/[^a]//g'|sort | tail -1)

当您想查看变量的内容时,请使用$var或首选${var} 随着{}大家都知道, other_chars${var}other_chars不是变量名的一部分。 ${#var}使用# ,您需要输入多个字符。 并且在使用echo时始终使用双引号,直到您了解

echo "The word with the highest number of a's has ${#most_a} of those"

现在,您可以在单词列表中以数字a代替该单词。 如果要使用至少4个a来grep字符串,则需要.* (任何字符重复0次或多次),因此grep表示a.*a.*a.*aa.*a.*a.*a.* 您可以告诉grep模式(a.*)重复了{4}{${#most_a}}次。 现在,您需要一些反斜杠来激活(){}字符的特殊含义,并开始将原始字符串拆分为单词:

echo "${string}" | tr " " "\n" | grep "\(a.*\)\{${#most_a}\}"

要打印字符串和数字,请使用类似

printf "%s %s\n" ${#most_a} $(echo "${string}" | tr " " "\n" | grep "\(a.*\)\{${#most_a}\}" )

awk可以处理以下问题:

string="1245aaa./ ssasaaa* kjdsaaa"

awk -v k='a' -v RS=' ' '{n = split($0, a, k)-1} 
     n > max{max=n; maxw=$0} END{print maxw, max}' OFS=, <<< "$string"

输出:

ssasaaa*,4

可以仅在Bash中执行此操作。

鉴于:

$ string="1245aaa./ ssasaaa* kjdsaaa"

您可以通过将当前IFS拆分为一个数组,将该字符串拆分为“ words”:

$ words=( $string )

然后遍历每个单词并计算正则表达式匹配项:

$ for word in "${words[@]}"
> do
> printf "%i %s\n" $(egrep -o 'a' <<<$word | wc -l) $word 
> done
3 1245aaa./
4 ssasaaa*
3 kjdsaaa

然后将结果按流水线sort以按匹配计数和head进行排序,以获得最高的:

for word in "${words[@]}"
do
    printf "%i %s\n" $(egrep -o 'a' <<<$word | wc -l) $word 
done | sort -n -r | head -1
4 ssasaaa*

awk效率更高,但是您也可以这样做。

 string="1245aaa./ ssasaaa* kjdsaaa"

 echo $string | tr ' ' '\n' | while read s
 do  
 echo "`echo $s | tr -dc 'a' | wc -c` $s"
 done | sort -nr

要么

echo $string | xargs -n 1 bash -c 'for s; do echo "`echo $s | tr -dc 'a' | wc -c` $s"; done' bash | sort -nr

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM