Code to count the number of sequential characters

Viewed 113

For example, if the input is aabcca, the output needs to be a2b1c2a1 not a3b1c2

I originally wrote this -

echo "aabcca" > file.txt
a=0
b=0
c=0

while IFS= read -r -n1 char
do

[ "$char" == "a" ] && (( a++ )) 
[ "$char" == "b" ] && (( b++ ))
[ "$char" == "c" ] && (( c++ ))
done < file.txt
echo "a${a}b${b}c${c}"

But this outputs a3b1c2. I want a2b1c2a1.

3 Answers

Using awk, you may do this:

awk '{
   p=c=""
   for (i=1; i<=length(); ++i) {
      f=substr($0, i, 1)
      if (p != "" && f != p) {
         printf "%s", p c
         c = 0
      }
      ++c
      p = f
   }
   print p c
}' file.txt
a2b1c2a1

How about:

#!/usr/bin/env bash

count=0
read -r -n1 prev_char < file.txt

while IFS= read -r -n1 char
do
    if [ "$prev_char" != "$char" ]
    then
        printf "%c%d" "$prev_char" "$count"
        count=0
    fi

    prev_char="$char"
    count=$((count + 1))

done < file.txt

printf "\n"

Here's an one-liner way to do it:

tr '\n' ' ' < file.txt | fold -w1 | uniq -c | awk '$2!=""{printf "%s", $2 $1} END {printf "\n"}'

EDIT: Also if you want to get rid of punctuation characters, just add this to tr:

tr '\n[:punct:]' ' ' < file.txt | fold -w1 | uniq -c | awk '$2!=""{printf "%s", $2 $1} END {printf "\n"}'
Related