2016-03-04 55 views
0

可以说我有存储在一个变量以下字符串:遍历字符串,并寻找某些字符外壳

字符串=“1245aaa./ ssasaaa * kjdsaaa”

有没有办法以某种方式循环通过这个字符串,发现它包含3个“单词”,所以可以说是用空格分隔的,而最“a”的单词是第二个单词,第二个单词中总共有4个“a”?

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

回答

1

另一种方法是对至少有n(在你的例子中为4)a's的行进行grepping。
首先你必须找到你需要grep的号码。
在步骤(请在评论中):
将字符串中的单词替换为换行符(tr,translate)空格。

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

随着sed 's/old/new/g'即可S(替补)旧字符串(模式)与新的字符串克(全球)。所以你可以echo "Have all characters a banned" | sed 's/a//g'。您想要替换除字符a之外的所有字符。 [^a]中的^代表not,[]代表一类字符。

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

你可以通过排序他们找到最长的字符串。排序后,最后一行最多。用tail -1得到最后一行:

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

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

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

如果你想看到一个变量的内容,使用$var或喜欢${var}。有了{}大家都知道${var}other_chars中的other_chars不是变量名的一部分。在${#var}#你要求一些字符。并采用回声时,直到你易懂

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

现在你可以grep使用此编号的的这个词的单词列表总是使用双引号。当你想grep至少有4个字符串的字符串时,你需要.*(任何字符重复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}\}") 
+0

谢谢。代码的第一位执行我正在寻找的功能。您能否就所使用的命令给出一些解释?我真的很感谢,因为这会为我节省大量的时间试图谷歌,并找出它们在这种情况下意味着什么。尤其是这部分:tr“”“\ n”| sed's/[^ a] // g'| sort |尾巴-1) – Daeto

+0

更新了我的答案。尝试每一行。 –

+0

非常感谢您的回复,这正是我需要的:) – Daeto

0

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 
+0

你应该提到这只是GNU awk。 ... – dawg

+0

我做了一个小改动,使它适用于GNU和非GNU(BSD)awk – anubhava

+0

感谢您的回复,但我在最后一行有几个问题n> max {max = n ; maxw = $ 0} END {print maxw,max}'OFS =,<<<“$ string”,我得到语法错误:意外重定向。另外,请您详细说明代码{n = split($ 0,a,k)-1}以及最后一行的含义是什么?提前致谢。 – Daeto

0

可以单独为此在猛砸。

考虑:

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

您可以通过打破当前IFS到一个数组打破串入“字”:

$ 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按匹配计数排序a第二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更有效,但你可以做到这样了。

0
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