-1

Hi folks just started write code in bash but stuck in my own question in want to count a to alphabets repetation in string like

read -p 'enter the string' str # SUPPOSE STRING USER ENTER IS

input = AAASSSSFFRREEE

i wanna get output like= A3S4F2R2E3

what can i do i am trying with for condition and this program is making monkey out of me

Ted Lyngmo
  • 93,841
  • 5
  • 60
  • 108
babybash
  • 13
  • 3

4 Answers4

0

One solution could be to loop over the string and strip away the first characters while counting them.

Example:

#!/bin/bash

IFS='' read -rp 'enter the string: ' str

res=''
# loop while the string is not empty
while [[ -n $str ]]
do
    # get the first character
    ch=${str:0:1}
    # create a regex matching the start of the string,
    # on one or more of the first character
    regex="^($ch+)"
    # perform the regex matching
    [[ "$str" =~ $regex ]]
    # the matching string
    match="${BASH_REMATCH[1]}"
    # concatenate the character + the count to the result
    res="$res$ch${#match}"
    # remove the matching characters from the string
    str=${str#"$match"}
done

# print the result
printf "%s\n" "$res"

Examples:

Input Output
AAASSSSFFRREEE A3S4F2R2E3
AAASSSSFFRREEEAAAFFFFFEE A3S4F2R2E3A3F5E2
Ted Lyngmo
  • 93,841
  • 5
  • 60
  • 108
0
  • grep -o, --only-matching

    Print only the matched (non-empty) parts of a matching line, with each such part on a separate output line. Using . as pattern for every character


grep -o . <<<"AASS"
A
A
S
S

  • uniq -c, --count

    prefix lines by the number of occurrences


grep -o . <<<"AASS"|uniq -c
      2 A
      2 S

  • awk '{printf "%s%d", $2,$1}'

    Reorder the output. Character '$2' first then number '$1'. Print all in a single line


grep -o . <<<"AASS"|uniq -c|awk '{printf "%s%d", $2,$1}END{print ""}'
A2S2

Unsorted alphabet

$ string="AAASSSSFFRREEE" 
$ grep -o . <<<"$string"|uniq -c|awk '{printf "%s%d", $2,$1}END{print ""}'
A3S4F2R2E3
$ string="AAASSSSFFRREEEAAAAFFFFFEE"
A3S4F2R2E3A4F5E2

Sorted alphabet

$ string="AAASSSSFFRREEE" 
$ grep -o . <<<"$string"|sort|uniq -c|awk '{printf "%s%d", $2,$1}END{print ""}'
A3E3F2R2S4
$ string="AAASSSSFFRREEEAAAAFFFFFEE"
A7E5F7R2S4
ufopilot
  • 3,269
  • 2
  • 10
  • 12
0

Using any awk:

$ cat tst.awk
{
    $0 = toupper($0)
    while ( char = substr($0,1,1) ) {
        printf "%s%d", char, gsub(char,"")
    }
    print ""
}

$ echo 'AAASSSSFFRREEE' | awk -f tst.awk
A3S4F2R2E3

The above assumes that the input doesn't contain any regexp metachars (you said it's to work on letters so that's fine) and you want the following output if the letters aren't all contiguous (you didn't answer @ArnaudValmary's question about that):

$ echo 'AAASSSSFFRREEEAAAFFFFFEE' | awk -f tst.awk
A6S4F7R2E5
Ed Morton
  • 188,023
  • 17
  • 78
  • 185
-1

Here's an awk-based solution that takes any unsorted input, and generates sorted output :

 echo 'ZZZCGGGGAAASSSWSFXXXRRRYYYUUUUYYFRREEEAAAAJBBBQQQAAQQQBFFFBFFPPEE' |

{m,n,g}awk '{
   
26      for(_= ( ___=(_^=_+=_^=_<_)^--_) + \
            _^((____="")*(___+=_^_)); _<___; _++) {

26         __ = sprintf("%c",_)             # if you`re not using nawk, then
                                            # combine this with sub() below
26         sub("$", (__) gsub(__,""), ____)
        }
 1      gsub("[A-Z]0","", ____)
 1      print ____
    }'


A9B5C1E5F7G4J1P2Q6R5S4U4W1X3Y5Z3
RARE Kpop Manifesto
  • 2,453
  • 3
  • 11