digit_to_word() {
case $1 in
4) echo "four" ;;
10) echo "ten" ;;
14) echo "fourteen" ;;
*) echo "$1" ;;
esac
}
write_input() {
cat <<'EOF'
I have two apples
He has 4 apples
They have 10 pizzas
4 score and 14 years ago
EOF
}
regex='([[:space:]])([0-9]+)([[:space:]])'
write_input |
while IFS= read -r line; do
line=" ${line} " # pad with space so first and last words work consistently
while [[ $line =~ $regex ]]; do # loop while at least one replacement is pending
pre_space=${BASH_REMATCH[1]} # whitespace before the word, if any
word=${BASH_REMATCH[2]} # actual word to replace
post_space=${BASH_REMATCH[3]} # whitespace after the word, if any
replace=$(digit_to_word "$word") # new word to use
in=${pre_space}${word}${post_space} # old word padded with whitespace
out=${pre_space}${replace}${post_space} # new word padded with whitespace
line=${line//$in/$out} # replace old w/ new, keeping whitespace
done
line=${line#' '}; line=${line%' '} # remove the padding we added earlier
printf '%s\n' "$line" # write the output line
done
ZGlnaXRfdG9fd29yZCgpIHsKCWNhc2UgJDEgaW4KCTQpIGVjaG8gImZvdXIiIDs7CgkxMCkgZWNobyAidGVuIiA7OwoJMTQpIGVjaG8gImZvdXJ0ZWVuIiA7OwoJKikgZWNobyAiJDEiIDs7Cgllc2FjCn0KIAp3cml0ZV9pbnB1dCgpIHsKCWNhdCA8PCdFT0YnCkkgaGF2ZSB0d28gYXBwbGVzCkhlIGhhcyA0IGFwcGxlcyAKVGhleSBoYXZlIDEwIHBpenphcwo0IHNjb3JlIGFuZCAxNCB5ZWFycyBhZ28KRU9GCn0KCnJlZ2V4PScoW1s6c3BhY2U6XV0pKFswLTldKykoW1s6c3BhY2U6XV0pJwoKd3JpdGVfaW5wdXQgfAp3aGlsZSBJRlM9IHJlYWQgLXIgbGluZTsgZG8KICBsaW5lPSIgJHtsaW5lfSAiICAjIHBhZCB3aXRoIHNwYWNlIHNvIGZpcnN0IGFuZCBsYXN0IHdvcmRzIHdvcmsgY29uc2lzdGVudGx5CiAgd2hpbGUgW1sgJGxpbmUgPX4gJHJlZ2V4IF1dOyBkbyAgICAgICAjIGxvb3Agd2hpbGUgYXQgbGVhc3Qgb25lIHJlcGxhY2VtZW50IGlzIHBlbmRpbmcKICAgIHByZV9zcGFjZT0ke0JBU0hfUkVNQVRDSFsxXX0gICAgICAgICAgICAgICAgIyB3aGl0ZXNwYWNlIGJlZm9yZSB0aGUgd29yZCwgaWYgYW55CiAgICB3b3JkPSR7QkFTSF9SRU1BVENIWzJdfSAgICAgICAgICAgICAgICAgICAgICMgYWN0dWFsIHdvcmQgdG8gcmVwbGFjZQogICAgcG9zdF9zcGFjZT0ke0JBU0hfUkVNQVRDSFszXX0gICAgICAgICAgICAgICAjIHdoaXRlc3BhY2UgYWZ0ZXIgdGhlIHdvcmQsIGlmIGFueQogICAgcmVwbGFjZT0kKGRpZ2l0X3RvX3dvcmQgIiR3b3JkIikgICMgbmV3IHdvcmQgdG8gdXNlCiAgICBpbj0ke3ByZV9zcGFjZX0ke3dvcmR9JHtwb3N0X3NwYWNlfSAgICAgICAgICMgb2xkIHdvcmQgcGFkZGVkIHdpdGggd2hpdGVzcGFjZQogICAgb3V0PSR7cHJlX3NwYWNlfSR7cmVwbGFjZX0ke3Bvc3Rfc3BhY2V9ICAgICAjIG5ldyB3b3JkIHBhZGRlZCB3aXRoIHdoaXRlc3BhY2UKICAgIGxpbmU9JHtsaW5lLy8kaW4vJG91dH0gICAgICAgICAgICAgICAgICAgICAgIyByZXBsYWNlIG9sZCB3LyBuZXcsIGtlZXBpbmcgd2hpdGVzcGFjZQogIGRvbmUKICBsaW5lPSR7bGluZSMnICd9OyBsaW5lPSR7bGluZSUnICd9ICAgICAgICAgICAgIyByZW1vdmUgdGhlIHBhZGRpbmcgd2UgYWRkZWQgZWFybGllcgogIHByaW50ZiAnJXNcbicgIiRsaW5lIiAgICAgICAgICAgICAgICAgICAgICAgICAjIHdyaXRlIHRoZSBvdXRwdXQgbGluZQpkb25l