0

I would like to find out the number of occurrences of each of the alphabets in a word. Eg

input
aabbbddd 
output
a@2 b@3 c@0 d@3

How can I perform this using shell script?

2
  • 1
    Is your input sorted by default?
    – cuonglm
    Commented Nov 17, 2014 at 6:28
  • Please clarify your question. Do you need c@0, since that is not a letter within the word?
    – slm
    Commented Nov 17, 2014 at 6:35

3 Answers 3

4

You could use sed, uniq, and sort:

$ echo -n "aabbbddd" | sed 's/\(.\)/\1\n/g'| sort | uniq -c
  2 a
  3 b
  3 d

The above uses sed to take each character and replace it with itself + a newline (\n). Now with each character on a newline (and sorted) you can use uniq -c to count the characters.

NOTE: This method will not show any of the characters in between that have zero occurrences.

Alternatively showing each letter's count

$ s="aabbbddd"; for i in {a..z}; do
     v=$(echo -n "$s" | grep -oi $i | wc -l); echo "$i : $v"; done
a : 2
b : 3
c : 0
d : 3
e : 0
f : 0
g : 0
h : 0
i : 0
j : 0
k : 0
l : 0
m : 0
n : 0
o : 0
p : 0
q : 0
r : 0
s : 0
t : 0
u : 0
v : 0
w : 0
x : 0
y : 0
z : 0

This works by looping through all the letters of the alphabet:

 for i in {a..z}; do .... ; done

Each iteration of the loop we grep through the string looking for a specific character, and use the -o option of grep to only return these matches. We then use wc -l to count how many occurrences of each letter we found, and store it in variable $v. We then display each iteration:

 echo "$i : $v"

NOTE: This approach can handle the strings being out of order.

2

These solutions are case-insensitive:

start cmd:> echo aabbbddd | 
  awk -v FS= '{for (i=1;i<=NF;i++) a[tolower($i)]++;}; 
    END {for (key in a) print key ": " a[key];}'
a: 2
b: 3
d: 3

Or for the complete alphabet:

start cmd:> echo Aabbbddd | 
  awk -v FS= '{for (i=1;i<=NF;i++) a[tolower($i)]++;};
    END {chars="abcdefghijklmnopqrstuvwxyz";
    for (i=1;i<27;i++) { key=substr(chars,i,1);print key ": " a[key]};}'
a: 2
b: 3
c: 
d: 3
e: 
f: 
g: 
h: 
i: 
j: 
k: 
l: 
m: 
n: 
o: 
p: 
q: 
r: 
s: 
t: 
u: 
v: 
w: 
x: 
y: 
z:
1
  • 1
    The output is missing c as OP's desired output.
    – cuonglm
    Commented Nov 17, 2014 at 6:31
0

Using only the shell (faster for short strings):

#! /bin/bash -
input=${*:-'aabbbddd'}

tmp=$input
arr=()
maxlen=0
maxchar=''
while ((${#tmp})); do
    firstchar=${tmp:0:1}
    next=${tmp//"$firstchar"}
    len=$((${#tmp}-${#next}))
    arr+=("$firstchar: $len")
    if ((maxlen<len)); then
    maxlen=$len
    maxchar=$firstchar
    fi
    tmp=$next
done

printf '%s\n' "${arr[@]}" 
echo "The char \"$maxchar\" appear $maxlen times in \"$input\""

Called as:

$ ./script
a@2 b@3 d@3 
The char "b" appear 3 times in "aabbbddd"

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .