Eu não vi uma opção interna, então aqui está uma ideia:
#!/bin/bash
str="$1"
regex='^[]0-9a-zA-Z,!^'@{}=().;/~_|[-]+$'
if [[ $str =~ $regex ]]
then
echo "matches"
echo "Match: ${BASH_REMATCH[0]}"
else
echo "doesn't match"
for (( i = 0; i < ${#str}; i++ )) do
c=${str:$i:1}
if [[ ! $c =~ $regex ]]
then
echo Non-matching character at index $i: "$c"
fi
done
fi
Ele simplesmente percorre o caractere $str
por caractere, comparando esse caractere com o $regex
.