shellshposixdash-shell

How to iterate over the characters of a string in a POSIX shell script?


A POSIX compliant shell shall provide mechanisms like this to iterate over collections of strings:

for x in $(seq 1 5); do
    echo $x
done

But, how do I iterate over each character of a word?


Solution

  • It's a little circuitous, but I think this'll work in any posix-compliant shell. I've tried it in dash, but I don't have busybox handy to test with.

    var='ab * cd'
    
    tmp="$var"    # The loop will consume the variable, so make a temp copy first
    while [ -n "$tmp" ]; do
        rest="${tmp#?}"    # All but the first character of the string
        first="${tmp%"$rest"}"    # Remove $rest, and you're left with the first character
        echo "$first"
        tmp="$rest"
    done
    

    Output:

    a
    b
    
    *
    
    c
    d
    

    Note that the double-quotes around the right-hand side of assignments are not needed; I just prefer to use double-quotes around all expansions rather than trying to keep track of where it's safe to leave them off. On the other hand, the double-quotes in [ -n "$tmp" ] are absolutely necessary, and the inner double-quotes in first="${tmp%"$rest"}" are needed if the string contains "*".