[SOLVED] Bash / grep regex validation for path names
ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
if ! echo $share | grep -q -e '[^-0-9A-Z_a-z]' -e '^[^0-9A-Za-z]' \
-e '[^0-9A-Za-z]$' -e '-_' -e '_-' ; then
echo OK
fi
This validates all constellations of A-Z and 0-9, etc., but I have problems with the "/" (can appear somewhere in the middle and at the end of the path) and "//" (at the beginning of the path, leading double-slashes).
Any help very much appreciated.
Thanks & regards,
jomann.
Click here to see the post LQ members have rated as the most helpful post in this thread.
if echo $1 | grep -x -E -e '//[-_A-Za-z0-9]+(/[-_A-Za-z0-9]*)*';
then
echo ' ok:' $1
else
echo 'bad:' $1
fi
The -x tells grep to only accept if the whole line is matched. The -E tells grep to use extended regular expressions, thus permitting the use of '+' to mean 'one or more occurrences'. The regular expression expects a double slash, followed by some non-empty text, optionally followed by zero or more path components each starting with a slash.
Of course, this will accept something like '//server_09/////' because a path component may be a slash by itself; up to you whether that is OK.
I offer a long test program that can be invoked with "bash regex2.sh -v"
However, I am not 100% happy because this expression succeeds when it should fail when presented with the sample:
/abad/file^name
Code:
#!/bin/bash
scriptname=${0##*/}
bre_filedirname='^([\/-_A-Za-z1-9\.]+[-_A-Za-z0-9\.]*)*$'
TESTNAME="Test of function regex (bfunc.regex) from"
TESTNAMELOC="https://github.com/sailnfool/bfunc"
USAGE="\n${0##*/} [-[hv]]\n
\t\tVerifies that the regular expression(s for filedirnames\n
\t\twork correctly.\n
\t\tNormally emits only PASS|FAIL message\n
\t-h\t\tPrint this message\n
\t-v\t\tVerbose mode to show values\n
"
localNUMARGS=0
optionargs="hv"
verbosemode="FALSE"
verboseflag=""
fail=0
while getopts ${optionargs} name
do
case ${name} in
h)
echo -e "${USAGE}" >&2
if [[ "${verbosemode}" == "TRUE" ]] ; then
echo -e "${DEBUG_USAGE}" >&2
fi
exit 0
;;
v)
verbosemode="TRUE"
verboseflag="-v"
;;
\?)
echo -e "invalid option: -$OPTARG" >&2
echo -e "${USAGE}" >&2
exit 1
;;
esac
done
shift $(( ${OPTIND} - 1 ))
if [[ $# -lt ${localNUMARGS} ]] ; then
echo -e "${0##*/} Insufficient arguments, expcted "\
"${localNUMARGS}, got $@" >&2
echo -e "${USAGE}" >&2
exit 2
fi
declare -a tv
declare -a tt
########################################################################
# tv is short for testvalue
# tt is short for testtype
########################################################################
tv+=("/")
tt+=(${bre_filedirname})
tv+=("//")
tt+=(${bre_filedirname})
tv+=("///")
tt+=(${bre_filedirname})
tv+=("/.")
tt+=(${bre_filedirname})
tv+=("/./")
tt+=(${bre_filedirname})
tv+=("/../.")
tt+=(${bre_filedirname})
tv+=("/usr/bin/b3sum")
tt+=(${bre_filedirname})
tv+=("/etc/dhcp/dhclient.conf")
tt+=(${bre_filedirname})
tv+=("/etc/dhcp/dhclient-exit-hooks.d")
tt+=(${bre_filedirname})
tv+=("/etc/gdm3/config-error-dialog.sh")
tt+=(${bre_filedirname})
for ((ti=0; ti<${#tv[@]}; ti++))
do
if [[ ! "${tv[${ti}]}" =~ ${tt[${ti}]} ]] ; then
((fail++))
if [[ "${verbosemode}" == "TRUE" ]] ; then
echo -e "Failed Test of ${tv[${ti}]}, " \
"expected ${tt[${ti}]}" >&2
fi
fi
done
declare -a fv
declare -a ft
########################################################################
# fv is short for failvalue
# ft is short for failtype
########################################################################
fv+=("/a bad/filename")
ft+=(${bre_filedirname})
fv+=("/abad/file^name")
ft+=(${bre_filedirname})
########################################################################
# In this case if the pattern match succeeds then it
# is broken
########################################################################
for ((ti=0; ti<${#fv[@]}; ti++))
do
if [[ "${fv[${ti}]}" =~ ${ft[${ti}]} ]] ; then
((fail++))
if [[ "${verbosemode}" == "TRUE" ]] ; then
echo -e "Failed Test succeeded with "\
"${fv[${ti}]},\n" \
"expected fail for ${ft[${ti}]}" >&2
fi
fi
done
exit ${fail}
Last edited by sailnfool; 09-14-2022 at 10:12 AM.
Reason: Removed -d option as extraneous
@sailinfool - You have replied to a thread that has been dormant for 10+ years, with an example that is not especially relevant to the question.
If you have a problem that you think to be similar, please open your own thread and post a minimal code example which illustrates your specific problem so that those currently active may provide relevant replies.
Please review the Site FAQ for guidance in asking well formed questions. Especially visit the link from that page, How to Ask Questions the Smart Way for discussion of things to consider when asking others for help.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.