Bash Script: Read One Character At A Time

I need to count one character at a time from input.txt. How do I read one character at a time under Linux / UNIX bash shell script?

The read builtin can read one character at a time and syntax is as follows:


read -n 1 c
echo $c

You can setup the while loop as follows:

# data file
# while loop
while IFS= read -r -n1 char
        # display one character at a time
	echo  "$char"
done < "$INPUT"

Example: Letter frequency counter shell script

# counter 
# Make sure file name supplied
[ $# -eq 0 ] && { echo "Usage: $0 filename"; exit 1; }
# Make sure file exits else die 
[ ! -f $INPUT ] && { echo "$0: file $INPUT not found."; exit 2; }
# the while loop, read one char at a time
while IFS= read -r -n1 c
	# counter letter a, b, c
	[ "$c" == "a" ] && (( a++ ))
	[ "$c" == "b" ] && (( b++ ))
	[ "$c" == "c" ] && (( cc++ ))
done < "$INPUT"
echo "Letter counter stats:"
echo "a = $a"
echo "b = $b"
echo "c = $cc"

Run it as follows:
/tmp/readch /etc/passwd
Sample outputs:

Letter counter stats:
a = 169
b = 104
c = 39

See also:

πŸ₯Ί Was this helpful? Please add a comment to show your appreciation or feedback.

nixCrat Tux Pixel Penguin
Hi! 🀠
I'm Vivek Gite, and I write about Linux, macOS, Unix, IT, programming, infosec, and open source. Subscribe to my RSS feed or email newsletter for updates.

9 comments… add one
  • lefty.crupps Oct 1, 2009 @ 12:27

    How about a script which runs Bash for me, but its output is slow, one-letter-at-a-time old school terminal looking? For example, when I run this script I am returned to a bash prompt; I run ”ls’ and the returning text is written as a single character every 1/2 second or so.

    Useless but I think it sounds retro and fun :)

  • DougTheBUg Jul 23, 2010 @ 23:45

    I don’t know about doing that with bash, but I think it would be cool for log files.

    # data file

    # while loop
    while IFS= read -r -n1 char
    # display one character at a time
    echo -n “$char”
    sleep .05
    done < "$INPUT"

  • DougTheBUg Jul 23, 2010 @ 23:46

    Ohh! You could ALSO, include aplay atinysound.wav after the echo line, so you get that uber-cool sound when text prints.

  • amir May 23, 2012 @ 20:59

    the tutorial was very good and usefull
    thank you in advance
    Amir from Iran

  • Luksz Apr 3, 2014 @ 16:32

    Hello Guys,
    This is great information covered here.
    When I try these examples all works perfectly except I cannot read space or tab as a character, instead I have empty $c variable.
    Do you know how to improve it to have the possiblity to read all characters including spaces and tabs?

  • Luksz Apr 3, 2014 @ 16:40

    Yes, my mistake :)
    when the variable
    is set empty as above then spaces can be red succssfully.

  • Meow Oct 19, 2014 @ 7:25

    The way using `read -r -n1` for reading every character is wrong, it can’t handle multi-byte characters.

    You should handle the characters in this way:

    string=”Hello world, δ½ ε₯½δΈ–η•Œ”
    for (( i = 0; i < ${#string}; i++ )); do
    echo $c
    # process every characters.

    The downside is the performance is not pretty good if your string is very long.

  • neze Dec 29, 2015 @ 10:29

    Would it then be slightly faster to do this ?


  • K_S May 26, 2016 @ 8:43

    Problems if the input is console instead of file:
    while IFS= read -r -n1 char
    echo “===$char===”
    done < "$INPUT"

Leave a Reply

Your email address will not be published. Required fields are marked *

Use HTML <pre>...</pre> for code samples. Your comment will appear only after approval by the site admin.