2016-03-04 125 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